Please help. How to read from xml sub tree. I have xml doc:
<data>
<Infos>
<Info>
<AddressFk>1</AddressFk>
<AddressLine1>1970</AddressLine1>
<AddressLine2>Napa Ct.</AddressLine2>
<Phone>
<dataAsString1>111111</string>
<dataAsString2>222222</string>
<dataAsString3>333333</string>
</Phone>
<City>Bothell</City>
</Info>
</Infos>
I read xml using XDocument:
XDocument xdoc = XDocument.Load("1.xml");
foreach (XElement addresList in xdoc.Document.Element("data").Elements("Infos").Elements("Info"))
{
address = new Address();
address.id = (string)addresList.Element("AddressFk");
address.Line1 = (string)addresList.Element("AddressLine1");
address.Line2 = (string)addresList.Element("AddressLine2");
address.City = (string)addresList.Element("City");
}
how to get the structure <Phone> ???
Use Elements
var phones = addresList.Element("Phone").Elements("string");
foreach(var phone in phones)
{
Console.WriteLine((string)phone);
}
for the future, it is bad practice to use tag names with reserved words
Related
I am trying to read an xml file (and later import the data in to a sql data base) which contains employees names address' etc.
The issue I am having is that in the xml the information for the address for the employee the node names are all the same.
<Employee>
<EmployeeDetails>
<Name>
<Ttl>Mr</Ttl>
<Fore>Baxter</Fore>
<Fore>Loki</Fore>
<Sur>Kelly</Sur>
</Name>
<Address>
<Line>Woof Road</Line>
<Line>Woof Lane</Line>
<Line>Woofington</Line>
<Line>London</Line>
</Address>
<BirthDate>1985-09-08</BirthDate>
<Gender>M</Gender>
<PassportNumber>123756rt</PassportNumber>
</EmployeeDetails>
</Employee>
I all other items are fine to extract and I have tried to use Linq to iterate through each "Line" node but it always just gives be the first Line and not the others.
var xAddreesLines = xEmployeeDetails.Descendants("Address").Select(x => new
{
address = (string)x.Element("Line").Value
});
foreach (var item in xAddreesLines)
{
Console.WriteLine(item.address);
}
I need to able to when I'm importing to my sql db that address line is separate variable
eg
var addressline1 = first <line> node
var addressline2 = second <line> node etc etc.
Any advice would be most welcome.
This should give you the expected output:-
var xAddreesLines = xdoc.Descendants("Address")
.Elements("Line")
.Select(x => new { address = (string)x });
You need to simply fetch the Line elements present inside Address node and you can project them. Also note there is no need to call the Value property on node when you use explicit conversion.
You can do it like this:
using System.Xml;
.
.
.
XmlDocument doc = new XmlDocument();
doc.Load("source.xml");
// if you have the xml in a string use doc.LoadXml(stringvar)
XmlNamespaceManager nsmngr = new XmlNamespaceManager(doc.NameTable);
XmlNodeList results = doc.DocumentElement.SelectNodes("child::Employee", nsmngr);
foreach (XmlNode result in results)
{
XmlNode namenode = result.SelectSingleNode("Address");
XmlNodeList types = result.SelectNodes("line");
foreach (XmlNode type in types)
{
Console.WriteLine(type.InnerText);
}
XmlNode fmtaddress = result.SelectSingleNode("formatted_address");
}
Refer to this question for the original source.
I am storing a xml in a string and using Xdocument i am parsing the string to xml from that i need to get xml element values and using that values i need to insert it in db. Any help would be appreciated.
XML:
<ListInventorySupplyResponse xmlns="http://mws.amazonaws.com/FulfillmentInventory/2010-10-01/">
- <ListInventorySupplyResult>
- <InventorySupplyList>
- <member>
<SellerSKU>043859634910</SellerSKU>
<FNSKU>X000IA4045</FNSKU>
<ASIN>B005YV4DJO</ASIN>
<Condition>NewItem</Condition>
<TotalSupplyQuantity>10</TotalSupplyQuantity>
<InStockSupplyQuantity>10</InStockSupplyQuantity>
- <EarliestAvailability>
<TimepointType>Immediately</TimepointType>
</EarliestAvailability>
<SupplyDetail />
</member>
</InventorySupplyList>
</ListInventorySupplyResult>
- <ResponseMetadata>
<RequestId>d50af29d-f203-4efc-a864-1725a59ded97</RequestId>
</ResponseMetadata>
</ListInventorySupplyResponse>
Code:
XDocument xd = XDocument.Parse(a);
string Sku = xd.Element();
var ASIN = xd.Descendants("ASIN");
var Condition = xd.Descendants("Condition");
var TotalSupplyQuantity = xd.Descendants("TotalSupplyQuantity");
You should use the xml namespace http://mws.amazonaws.com/FulfillmentInventory/2010-10-01/
var xDoc = XDocument.Parse(xml);
XNamespace ns = "http://mws.amazonaws.com/FulfillmentInventory/2010-10-01/";
var condition = (string)xDoc.Descendants(ns + "Condition").First();
OR
you can search for Tag Condition in any xml namespace
var condition2 = (string)xDoc.Descendants()
.First(d => d.Name.LocalName == "Condition");
OR
you can use XPath to get Condition in any xml namespace
var condition3 = (string)xDoc.XPathSelectElement("//*[local-name()='Condition']");
Use this:
string value = xd.Root.Element("SellerSKU").Value;
I want to create a dictionary for the following xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<groups>
<group>
<data>Open</data>
<aggregation>5</aggregation>
</group>
</groups>
I want my dictionary to get the values as:
Open,5
Please note that 'Open' is fetched from <data>Open</data> and '5' is fetched from <aggregation>5</aggregation>.
My current code is as follows:
foreach (XmlNode group in Bugsagg)
{
XmlNode data = group.SelectSingleNode(".//data");
XmlNode aggregate = group.SelectSingleNode(".//aggregation");
if (Dict_Aggregate.ContainsKey(data.InnerText))
{
Dict_Aggregate[data.InnerText]++;
}
else
{
Dict_Aggregate.Add(data.InnerText, 1);
}
I am not getting the desired response. Please suggest where i am doing wrong.Thanks
Use XElement and LINQ to XML.
You should add
using System.Xml;
using System.Xml.Linq;
on top of your code. Then use the following
string xml = #"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><groups><group><data>Open</data><aggregation>5</aggregation></group></groups>";
XElement xe = XElement.Parse(xml);
Dictionary<string,string> d =
xe.Elements("group")
.ToDictionary
(
x=>(string)x.Element("data"), //Key Selector
z=>(string)z.Element("aggregation")//Value Selector
);
Some people might also suggest to use an XDocument as you provide a fully qualified xml with declaration etc:
XDocument xd = XDocument.Parse(xml);
Dictionary<string,string> d =
xd.Root.Elements("group")
.ToDictionary
(
x=>(string)x.Element("data"), //Key Selector
z=>(string)z.Element("aggregation")//Value Selector
);
<Peoples>
<People>
<Name>RadheyJang</Name>
<Location>India</Location>
<Work>Software Developer</Work>
<Point>5</Point>
<details>
<People>
<Name>ArunaTiwari</Name>
<Location>India</Location>
<Work>SoFtwareCoder</Work>
<Point>3</Point>
<details/>
<Test>A</Test>
</People>
</details>
<Test>NA</Test>
</People>
</Peoples>
I am able to Read That Xml By using below code .
XDocument xmlDoc = XDocument.Load(str);
var vrresult = from a in xmlDoc.Descendants("People")
select new
{
Name= a.Element("Name").Value,
Location= a.Element("Location").Value,
Point= a.Element("Point").Value
};
GridView1.DataSource = vrresult;
GridView1.DataBind();
But It is reading the Contents of details also . I want to Skip reading the Content inside the details Element . Please let me know how can i skip the Content Inside the details .
You need to use XPath for this...
using System.Xml.XPath;
string xml = #"
<Peoples>
<People>
<Name>RadheyJang</Name>
<Location>India</Location>
<Work>Software Developer</Work>
<Point>5</Point>
<details>
<People>
<Name>ArunaTiwari</Name>
<Location>India</Location>
<Work>SoFtwareCoder</Work>
<Point>3</Point>
<details/>
<Test>A</Test>
</People>
</details>
<Test>NA</Test>
</People>
</Peoples>";
XDocument xmlDoc = XDocument.Parse(xml);
var vrresult = from a in xmlDoc.XPathSelectElements("/Peoples/People")
select new
{
Name = a.Element("Name").Value,
Location = a.Element("Location").Value,
Point = a.Element("Point").Value
};
var ele = XElement.Parse(xml);
// change to XElement.Load if loading from file
var result = ele.Descendants("Section").Zip(ele.Descendannt("Mark"), (s,m) => new {Section = s.Value, Mark = m.Value}); Now you can create your DataTable:
var table = new DataTable();
var marks = new DataColumn("Mark");
var sections = new DataColumn("Sections");
table.Columns.Add(marks); table.Columns.Add(sections);
foreach (var item in result)
{
var row = table.NewRow();
row["Mark"] = item.Mark;
row["Sections"] = item.Section;
table.Rows.Add(row);
}
Try this Code ..
The only thing I can think of is that the XML is not legal:
<Peoples>
<People> *You have an opening People tag here*
<Name>RadheyJang</Name>
<Location>India</Location>
<Work>Software Developer</Work>
<Point>5</Point>
<details> *You create a details tag here*
<People> *You generate the same tag inside of another People tag*
<Name>ArunaTiwari</Name>
<Location>India</Location>
<Work>SoFtwareCoder</Work>
<Point>3</Point>
<details/> *Then you close the details tag here*
<Test>A</Test>
</People>
</details> *Then you close another one, but there is not a second opening detail tag*
<Test>NA</Test>
</People>
</Peoples>
I'm not sure if this helps at all, but you might want to consider fixing up your XML.
In my previous question here, I didn’t understand how to solve my problem.
Linq to XML, how to acess an element in C#?
Here is my XML I need to parse:
<root>
<photo>/filesphoto.jpg</photo>
<photo:mtime>12</photo:mtime>
<text>some text</text>
</root>
To access the element I use this code:
var doc = XDocument.Parse(xml.Text);
doc.Descendants("text").FirstOrDefault().Value;
How can I access ?
I have try http://aspnetgotyou.blogspot.com/2010/06/xdocument-or-xelement-with-xmlnamespace.html,
But it is ignored <photo:mtime> and I need to access it.
Please write some code.
Contrary to #BrokenGlass' comments, your XML is not invalid. In fact the technique in the link you provided in your question (for loading namespaces) works fine. Maybe you just didn't change the example for your own needs. Here's a more compact generalization for parsing xml fragments with namespaces into an XElement:
public static XElement parseWithNamespaces(String xml, String[] namespaces) {
XmlNamespaceManager nameSpaceManager = new XmlNamespaceManager(new NameTable());
foreach (String ns in namespaces) { nameSpaceManager.AddNamespace(ns, ns); }
return XElement.Load(new XmlTextReader(xml, XmlNodeType.Element,
new XmlParserContext(null, nameSpaceManager, null, XmlSpace.None)));
}
Using your exact input:
string xml =
#"<root>
<photo>/filesphoto.jpg</photo>
<photo:mtime>12</photo:mtime>
<text>some text</text>
</root>";
XElement x = parseWithNamespaces(xml, new string[] { "photo" });
foreach (XElement e in x.Elements()) {
Console.WriteLine("{0} = {1}", e.Name, e.Value);
}
Console.WriteLine(x.Element("{photo}mtime").Value);
Prints:
photo = /filesphoto.jpg
{photo}mtime = 12
text = some text
12
Try this: (Your xml is changed a little, see )
string xml = "<root><photo>/filesphoto.jpg</photo><photoMtime>12</photoMtime><text>some text</text></root>";
var doc = XDocument.Parse(xml);
string value = doc.Descendants("text").FirstOrDefault().Value;
MessageBox.Show(value);