Linq To Xml problems using XElement's method Elements(XName) - c#

I have a problem using Linq To Xml.
A simple code. I have this XML:
<?xml version="1.0" encoding="utf-8" ?>
<data xmlns="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/directory file.xsd">
<contact>
<name>aaa</name>
<email>email#email.ext</email>
<birthdate>2002-09-22</birthdate>
<telephone>000:000000</telephone>
<description>Description for this contact</description>
</contact>
<contact>
<name>sss</name>
<email>email#email.ext</email>
<birthdate>2002-09-22</birthdate>
<telephone>000:000000</telephone>
<description>Description for this contact</description>
</contact>
<contact>
<name>bbb</name>
<email>email#email.ext</email>
<birthdate>2002-09-22</birthdate>
<telephone>000:000000</telephone>
<description>Description for this contact</description>
</contact>
<contact>
<name>ccc</name>
<email>email#email.ext</email>
<birthdate>2002-09-22</birthdate>
<telephone>000:000000</telephone>
<description>Description for this contact</description>
</contact>
I want to get every contact mapping it on an object Contact. To do this I use this fragment of code:
XDocument XDoc = XDocument.Load(System.Web.HttpRuntime.AppDomainAppPath + this.filesource);
XElement XRoot = XDoc.Root;
//XElement XEl = XElement.Load(this.filesource);
var results = from e in XRoot.Elements("contact")
select new Contact((string)e.Element("name"), (string)e.Element("email"), "1-1-1", null, null);
List<Contact> cntcts = new List<Contact>();
foreach (Contact cntct in results) {
cntcts.Add(cntct);
}
Contact[] c = cntcts.ToArray();
// Encapsulating element
Elements<Contact> final = new Elements<Contact>(c);
Ok just don't mind that all: focus on this:
When I get the root node, it is all right, I get it correctly.
When I use the select directive I try to get every node saying: from e in
XRoot.Elements("contact")
OK here's the problem: if I use: from e in XRoot.Elements() I get all contact nodes, but if I use: from e in XRoot.Elements("contact") I GET NOTHING: Empty SET.
OK you tell me: Use the other one: OK I DO SO, let's use:
from e in XRoot.Elements(), I get all nodes anyway, THAT's RIGHT BUT HERE COMES THE OTHER PROBLEM:
When Saying: select new Contact((string)e.Element("name"), (string)e.Element("email"), "1-1-1", null, null); I Try to access <name>, <email>... I HAVE TO USE .Element("name") AND IT DOES NOT WORK TOO!!!!!!!!WHAT THE HELL IS THIS????????????? IT SEEMS THAT I DOES NOT MATCH THE NAME I PASS But how is it possible. I know that Elements() function takes, overloaded, one argument that is an XName which is mapped onto a string. Please consider that the code I wrote come from an example, It should work.

Pretty easy: there's a XML namespace in play, which you're ignoring:
<data xmlns="http://www.example.com"
**************************
You need to add that to your Linq-to-XML queries!
Something like:
XNamespace ns = "http://www.example.com";
and then
XRoot.Elements(ns + "contact")
and of course, also use the XML namespace when accessing the child elements:
var results = from e in XRoot.Elements("contact")
select new Contact(e.Element(ns + "name").Value,
e.Element(ns + "email").Value,
"1-1-1", null, null);
That should help. See the MSDN docs on Working with XML Namespaces for more details.

For me I solved it like that because I didn't had a namespace in my XML:
xmldoc.Root.Elements("contact");
I forgot to use the "Root" method.

Related

Access Child nodes with namespace using xpath

How can I read the content of the childnotes using Xpath?
I have already tried this:
var xml = new XmlDocument();
xml.Load("server-status.xml");
var ns = new XmlNamespaceManager(xml.NameTable);
ns.AddNamespace("ns", "namespace");
var node = xml.SelectSingleNode("descendant::ns:server[ns:ip-address]", ns)
Console.WriteLine(node.InnerXml)
But I only get a string like this:
<ip-address>127.0.0.50</ip-address><name>Server 1</name><group>DATA</group>
How can I get the values individually?
Xml file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<server-status xmlns="namespace">
<server>
<ip-address>127.0.0.50</ip-address>
<name>Server 1</name>
<group>DATA</group>
</server>
</server-status>
You're using XML namespaces in XPath correctly.
However, your original XPath,
descendant::ns:server[ns:ip-address]
says to select all ns:server elements with ns:ip-address children.
If you wish to select the ns:ip-address children themselves, instead use
descendant::ns:server/ns:ip-address
Similarly, you could select ns:name or ns:group elements.

C# Xpath can't get element by name

Have document loaded to XmlDocument with next srtucture
<?xml version="1.0" encoding="UTF-8"?>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink">
<stylesheet type="text/css"></stylesheet>
<description>...</description>
<body>...</body>
<binary id="19317.jpg" content-type="image/jpeg">...</binary>
</FictionBook>
Next metods return me null (or empty collection if i use SelectNodes):
doc.SelectSingleNode("body");
doc.SelectSingleNode("//body");
doc.LastChild.SelectSingleNode("body");
doc.LastChild.SelectSingleNode("//body");
But this one works correctly
doc.LastChild["body"];
Why XPath don't give me any results?
doc.SelectSingleNode("//body"); doesn't work because body is declared in a specific namespace "http://www.gribuser.ru/xml/fictionbook/2.0", so to query for it you could code it like this:
var mgr = new XmlNamespaceManager(new NameTable());
mgr.AddNamespace("whatever", "http://www.gribuser.ru/xml/fictionbook/2.0");
var node = doc.SelectSingleNode("//whatever:body", mgr);
doc.LastChild["body"]; works because the implementation supports it, but you could use it like this to avoid ambiguities:
doc.LastChild["body", "http://www.gribuser.ru/xml/fictionbook/2.0"]

LINQ TO XML retrieving Child Element Value

I have the following XML
<ABC xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ns.hr-xml.org/2007-04-15">
<ReceiptId>
<IdValue>123</IdValue>
</ReceiptId>
<ClientOrderId>
<IdValue>345</IdValue>
</ClientOrderId>
<AccessPoint>
<Description>My Description</Description>
</AccessPoint>
<ABCStatus>
<Status>Error</Status>
<Details>ERRORS:
Talent is already in an active process for this opening.
</Details>
<StatusDate>2015-08-05</StatusDate>
</ABCStatus>
</ABC>
I am trying to retrieve the element value 345 nested in IdValue and ClientOrderId
I have used the Linq to xml code in C# to retrieve the value with no luck
XDocument XMLResults = XDocument.Parse(sResult);
var sClientOrderID =
from nodeAElem in XMLResults.Root.Elements("ABC")
from nodeA1Elem in nodeAElem.Elements("ClientOrderId")
from nodeA11Elem in nodeA1Elem.Elements("IdValue")
select nodeA11Elem.Value;
also need to retrieve the Status Elements value which is Error for the above xml.
Any help is greatly appreciated
Your XML document is using a namespace, you have to use it in your query to make it work.
Root already brings you to ABC element, so you don't have to call Elements("ABC")
You're looking for single value, so you probably want to use Element instead of Elements.
var ns = (XNamespace)"http://ns.hr-xml.org/2007-04-15";
var sClientOrderID = (int)XMLResults.Root
.Element(ns + "ClientOrderId")
.Element(ns + "IdValue");

Select last XML node

I have this XML code:
<AriaGostarInformation>
<MenuInformation>
<MenuNames Name="0" href="default.aspx">home</MenuNames>
<SubMenuNames parentName="1">
fgfgfgfgs
</SubMenuNames>
<SubMenuNames parentName="3">
</SubMenuNames>
</MenuInformation>
<SliderInformation>
<SliderImageAddress>..\..\Img\Hydrangeas.jpg,</SliderImageAddress>
<SliderImageAddress>..\..\Img\Jellyfish.jpg,</SliderImageAddress>
<SliderImageAddress>..\..\Img\Koala.jpg,</SliderImageAddress>
<SliderImageAddress>..\..\Img\Lighthouse.jpg,</SliderImageAddress>
<SliderImageAddress>..\..\Img\Penguins.jpg,</SliderImageAddress>
<SliderImageAddress>..\..\Img\Tulips.jpg,</SliderImageAddress>
</SliderInformation>
<LastProductInformation>
<Product Name="147">
<Subject>
</Subject>
<ProductImageAddress>http://localhost:1209/ckeditor/plugins/imagebrowser/browser/Hydrangeas.jpg</ProductImageAddress>
<ProductDes>
<p><span style="color:#FFA07A;">qwqweqweqe</span>qwe</p>
<p><span style="font-size:11px;">qweqweqw</span>e</p>
</ProductDes>
</Product>
<Product Name="dsa">
<Subject>salm</Subject>
<ProductImageAddress>http://localhost:1209/ckeditor/plugins/imagebrowser/browser/Hydrangeas.jpg</ProductImageAddress>
<ProductDes>
<p>sdADASDASDASDASDASDASD</p>
<p>ASDASDASDADASDASDASDASDA</p>
<p>ASDASDASDASDASDASDASDASDASD</p>
</ProductDes>
</Product>
</LastProductInformation>
</AriaGostarInformation>
I want select last product node in LastProductInformation and get this node's attribute.
My code is:
XmlDocument xdoc = new XmlDocument();
xdoc.Load(AppDomain.CurrentDomain.BaseDirectory + #"\static\css\xml\data.xml");
XmlNode xparent = xdoc.SelectSingleNode("//LastProductInformation");
var b = xparent.SelectSingleNode("/Product[last()]").Attributes["Name"].Value;
but this returns null. What should I do?
Using LINQ to XML
var value = XDocument.Load("path")
.Descendants("Product")
.Last()
.Attribute("Name").Value;
Also you can use XPath with LINQ to XML
var value = XDocument.Load("path")
.XPathSelectElement("//LastProductInformation/Product[last()]")
.Attribute("Name").Value;
Note: Make sure you have a reference to System.Xml.Linq namespace from your project.
You don't have to change to linq.
var b = xparent.SelectSingleNode("//Product")[last()].Attributes["Name"].Value;
The last() works like an index so should be at the end.

How to get child and grandchild elements from XML element?

So, I have an XElement, that contains multiple child elements. I can successfully declare the XElement, and write it to a file:
Test.project:
<?xml version="1.0" encoding="utf-8"?>
<project>
<child>
<grand-child1>
<great-grand-child1>Hello There!</great-grand-child1>
<great-grand-child2>Hello World!</great-grand-child2>
</grand-child1>
<grand-child2>Testing 123...</grand-child2>
</child>
</project>
Then I'm trying to read from the file. I searched for ways to get child and grand-child nodes, and found I can use XElement.XPathSelectElement(). The problem is, Visual C# doesn't recognize XPathSelectElement as a method for an XElement. I've searched for usage examples for the method, and they all say to use XElement.XPathSelectElement.
For example, I tried:
x_el = new XElement("project",
new XElement("child",
new XElement("grand-child", "Hello World!")
);
string get_string = x_el.XPathSelectElement("child/grand-child");
...but XPathSelectElement is not recognized. What am I doing wrong?
You need to add System.Xml.XPath namespace as well
like
using System.Xml.XPath;
after that try below
x_el = new XElement("project",
new XElement("child",
new XElement("grand-child", "Hello World!")
));
// XPathSelectElement method return XElement not string , use var or XElement
XElement element = x_el.XPathSelectElement("child/grand-child");
string get_string = element.ToString()
Or
var get_string = x_el.XPathSelectElement("child/grand-child").ToString();

Categories

Resources