Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing complex XML with C#

I am trying to parse a complex XML with C#, I am using Linq to do it. Basically, I am doing a request to a server and I get XML, this is the code:

XElement xdoc = XElement.Parse(e.Result);
this.newsList.ItemsSource = 
  from item in xdoc.Descendants("item")
  select new ArticlesItem
  {
    //Image = item.Element("image").Element("url").Value,
    Title = item.Element("title").Value,
    Description = this.Strip(item.Element("description").Value).Substring(0, 200).ToString()
  }

And this is the XML structure:

<item>
  <test:link_id>1282570</test:link_id>
  <test:user>SLAYERTANIC</test:user>
  <title>aaa</title>
  <description>aaa</description>
</item>

How I can access to the property test:link_id for example?

Thanks!

like image 975
ssola Avatar asked Dec 17 '22 13:12

ssola


2 Answers

Currently your XML is invalid since the test namespace is not declared, you can declare it like this:

<item xmlns:test="http://foo.bar">
  <test:link_id>1282570</test:link_id>
  <test:user>SLAYERTANIC</test:user>
  <title>aaa</title>
  <description>aaa</description>
</item>

Having this you can use XNamespace to qualify the XML element you want with the correct namespace:

XElement xdoc = XElement.Parse(e.Result);
XNamespace test = "http://foo.bar";
this.newsList.ItemsSource = from item in xdoc.Descendants("item")
                            select new ArticlesItem
                            {
                                LinkID = item.Element(test + "link_id").Value,
                                Title = item.Element("title").Value,
                                Description = this.Strip(item.Element("description").Value).Substring(0, 200).ToString()
                            }
like image 92
BrokenGlass Avatar answered Dec 24 '22 14:12

BrokenGlass


To write a query on XML that is in a namespace, you must use XName objects that have the correct namespace. For C#, the most common approach is to initialize an XNamespace using a string that contains the URI, then use the addition operator overload to combine the namespace with the local name.

To retrieve the value of the link_id element you will need to declare and use an XML namespace for the test:link element.

Since you did not show the namespace declaration in your example XML, I am going to assume it is declared somewhere elese in the XML document. You need to locate the namespace declaration in the XML ( something like xmlns:test="http://schema.example.org" ) which is often declared in the root of the XML document.

After you know this, you can do the following to retrieve the value of the link_id element:

XElement xdoc = XElement.Parse(e.Result);

XNamespace testNamespace = "http://schema.example.org";

this.newsList.ItemsSource = from item in xdoc.Descendants("item")
  select new ArticlesItem
  {
    Title       = item.Element("title").Value,
    Link        = item.Element(testNamespace + "link_id").Value,
    Description = this.Strip(item.Element("description").Value).Substring(0, 200).ToString()                            
  }

See the XNamespace and Namespaces in C#, and How to: Write Queries on XML in Namespaces for further information.

like image 32
Oppositional Avatar answered Dec 24 '22 13:12

Oppositional