string xml = #"<AllBands >
<Band>
<Name ID=""1234"" started=""1962"">Beatles<![CDATA[lalala]]></Name>
<Last>1</Last>
<Salary>2</Salary>
</Band>
<Band>
<Name ID=""222"" started=""1968"">Doors<![CDATA[lalala]]></Name>
<Last>1</Last>
<Salary>2</Salary>
</Band>
</AllBands>";
XmlReader reader = XmlReader.Create(new StringReader(xml));
XElement root = XElement.Load(reader);
var child1 = root.XPathSelectElements(#"/AllBands/Band" );
child1 has no childs !
What am i missing ?
root does not refer to the XML document, it refers to the AllBands element since you loaded it using XElement.Load(). So your XPATH should be relative to that element.
var children = root.XPathSelectElements("Band");
Related
Hi I try to read an xml file with LINQ.
The name of the file is:categorizedBooks.xml
and the content of the file looks like this:
<category name=".NET">
<books>
<book>CLR via C#</book>
<book>Essential .NET</book>
</books>
</category>
The code for reading the file looks like this:
XElement rootss = XElement.Load(#"D:/categorizedBooks.xml");
XElement dotNetCategoryss = rootss.Element("category");
XAttribute namehallo = dotNetCategoryss.Attribute("name");
XElement booksss = dotNetCategoryss.Element("books");
IEnumerable<XElement> bookElements = booksss.Elements("book");
Console.WriteLine((string)dotNetCategoryss);
foreach (XElement bookElement in bookElements)
{
Console.WriteLine(" - " + (string)bookElement);
}
But i get null on this line:
XAttribute namehallo = dotNetCategoryss.Attribute("name");
So how to fix this , so that it not will be null?
Thank you
Your doc root is the category element - try:
XAttribute namehallo = rootss.Attribute("name");
Console.WriteLine(namehallo.Value);
You'll have to change your other XElement references similarly
instead of XElement.Load use XDocument.Load or XDocument.Parse
var xml = #"
<category name='.NET'>
<books>
<book>CLR via C#</book>
<book>Essential .NET</book>
</books>
</category>";
var document = XDocument.Parse(xml);
// returns: .NET
var category = document
.Element("category")
.Attributes("name")
.Select(p => p.Value);
// returns: CLR via C#, Essential .NET
var books = document
.Descendants("book")
.Select(p => p.Value);
I'm having this XML document with namespaces and I want to extract some nodes using XPath.
Here's the document:
<ArrayOfAnyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<anyType xsi:type="Document">
<Id>5</Id>
<Title>T1</Title>
</anyType>
<anyType xsi:type="Document">
<Id>15</Id>
<Title>T15</Title>
</anyType>
</ArrayOfAnyType>
What's the XPath expression going to be if I want to extract all "anyType" elements with xsi:type="Document"?
I've tried this:
//anyType[#xsi:type="Document"]
and it doesn't work:
If you are using C# then you need to specify the namespace for the "anyType" element in your XPath:
var xml = new XmlDocument();
xml.LoadXml( "your xml" );
var names = new XmlNamespaceManager( xml.NameTable );
names.AddNamespace( "xsi", "http://www.w3.org/2001/XMLSchema-instance" );
names.AddNamespace( "a", "http://tempuri.org/" );
var nodes = xml.SelectNodes( "//a:anyType[#xsi:type='Document']", names );
I think that
//anyType[namespace-uri() = "http://www.w3.org/2001/XMLSchema-instance"][local-name() = "type"]
Will do what you want.
This way you don't need to specify namespace:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("your xml");
XmlNode node = xmlDoc.SelectSingleNode("/*[local-name() = 'anyType']");
XmlNode nodeToImport = xmlDoc2.ImportNode(node, true);
xmlDoc2.AppendChild(nodeToImport);
Had nearly the same problem, I forgot to add the correct namespace for xsi:type
(http://www.w3.org/2001/XMLSchema-instance) was using http://www.w3.org/2001/XMLSchema
and I did never get any result - now it is working the following way:
<xsl:value-of select="/item1/item2/item3/#xsi:type"></xsl:value-of>
I am trying to parse a xml that I got as response to webservice response the xml is shown below
<GeneralSearchResponse>
<serverDetail></serverDetail>
<exceptions exceptionCount="1"></exceptions>
<clientTracking height="19" type="logo" width="106"></clientTracking>
<searchHistory></searchHistory>
<categories matchedCategoryCount="1" returnedCategoryCount="1">
<category id="0">
<name>bart</name>
<categoryURL>http://www.shopping.com/bart/products?oq=bart&linkin_id=7000610
</categoryURL>
<items matchedItemCount="1045" pageNumber="1" returnedItemCount="5">
<product id="130506037"></product>
<product id="104483377"></product>
<offer featured="false" id="tp-VCdOoO1RL6xICeRONqg==" smartBuy="false" used="false"></offer>
<offer featured="false" id="12evWWi57lddzFufngUWsg==" smartBuy="false" used="false"></offer>
<product id="96754577"></product>
</items>
<attributes matchedAttributeCount="5" returnedAttributeCount="5"></attributes>
<contentType>hybrid</contentType>
</category>
<intActualCategoryCount>4</intActualCategoryCount>
</categories>
<relatedTerms></relatedTerms>
</GeneralSearchResponse>
But when I am trying to parse using following code I am not able to get any descend or any node
XDocument xDoc = new XDocument();
xDoc = XDocument.Parse(data);
var xEle = xDoc.Root.Descendants("categories");
But xEle is not having any categories. Please let me know what is the issue??
Your XML has a default namespace - so the elements in it are in that namespace. The methods which find elements in LINQ to XML are namespace sensitive. You want:
XNamespace ns = "urn:types.partner.api.shopping.com";
XDocument xDoc = new XDocument();
xDoc = XDocument.Parse(data);
var xEle = xDoc.Root.Descendants(ns + "categories");
<root>
<element1>innertext</element1>
<element2>innertext</element2>
<element3>
<child1>innertext</child1>
</element3>
</root>
I have an xml structure shown above.
I would like to "append" the xml file (it is already created) to add another "child" inside element3>, so that it will look like this:
<root>
<element1>innertext</element1>
<element2>innertext</element2>
<element3>
<child1>innertext</child1>
<child2>innertext</child2>
</element3>
</root>
Linq to xml and/or Xpath would be great
EDIT:
I have tried doing this:
XElement doc = XElement.Load(mainDirectory);
XElement newElem = doc.Elements("element3").First();
newElem.Add(new XElement("child2", "child2innertext"));
doc.Add(newElem);
doc.Save(mainDirectory);
XmlDocument xDoc = new XmlDocument();
xDoc.Load("filename.xml");
foreach (XmlNode xNode in xDoc.SelectNodes("/root/element3"))
{
XmlElement newElement = xDoc.CreateElement("Child2");
xNode.AppendChild(newElement);
xNode.InnerText = "myInnerText";
}
With XDocument you can achieve this as:
string xml = "<root><element1>innertext</element1><element2>innertext</element2><element3><child1>innertext</child1></element3></root>";
var doc = XDocument.Parse(xml); //use XDocument.Load("filepath"); in case if your xml is in a file.
var el3 = doc.Descendants("element3").FirstOrDefault();
el3.Add(new XElement("child2", "innertext"));
Please, try this LINQPAD example
void Main()
{
var xml =
#"<root>
<element1>innertext</element1>
<element2>innertext</element2>
<element3>
<child1>innertext</child1>
</element3>
</root>";
var doc = XDocument.Parse(xml);
doc.Root.Element("element3")
.Add(new XElement("child2", "innertext"));
doc.Dump();
}
I have a XML file:
<SourceMessage xmlns="test.test">
<updated>2011</updated>
<title type="p1"/>
<title type="p2"/>
<title type="p3"/>
<entry>
</entry>
</SourceMessage>
How could I use LINQ to get the <type> attribute of the <title> element, i.e. "p1", "p2" and "p3"?
Use XDocument.Load or XDocument.Parse to load the XML data into an XDocument. Then, using LINQ, you can get the type for each <title> element under the document root as follows:
XNamespace test = "test.test";
XDocument doc = XDocument.Load(file);
// - or -
XDocument doc = XDocument.Parse("<SourceMessage ...");
IEnumerable<string> query = from title in doc.Root.Elements(test + "title")
select (string)title.Attribute("type");
foreach (string item in query)
{
Console.WriteLine(item);
}
Output:
p1
p2
p3
var xElement XElement.Parse(xmlString);
var result = xElement.Descendants("title")
.Select(e => e.Attribute("type").Value);
XDocument xml = XDocument.Parse (#"<SourceMessage xmlns="test.test">
<updated>2011</updated>
<title type="p1"/>
<title type="p2"/>
<title type="p3"/>
<entry>
</entry>
</SourceMessage>");
foreach (var t in xml.Root.Descendants("title"))
Console.Write(t.Attribute("type").Value);