napi15
napi15

Reputation: 2402

How to get element by element from XmlDocument

I was able to get my first element from this list

 <?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <GetITARListResponse xmlns="http://tempuri.org/">
      <GetITARListResult>
        <ClassificationCode>
          <code>dsd</code>
          <description>toto</description>
          <legislation>d/legislation>
        </ClassificationCode>
        <ClassificationCode>
          <code>dsd</code>
          <description>tata</description>
          <legislation>dsd</legislation>
        </ClassificationCode>
        <ClassificationCode>
          <code>code2</code>
          <description>dsds</description>
          <legislation>dsd</legislation>
        </ClassificationCode>

by writing

XDocument result = new XDocument();
result  =   ExportControl.ResultXML;
var codes = HttpContext.Current.Server.MapPath("~/XML_Templates/codes.xml");
dynamic root = new ExpandoObject();
XmlToDynamic.Parse(root, xDoc.Elements().First());
var result = xDoc.Descendants(XNamespace.Get("http://tempuri.org/") + "code").First();

which get the the first code "dsd". But what if I want a foreach and get all the code? or what if I want a certain code ? for example

var result = xDoc.Descendants(XNamespace.Get("http://tempuri.org/") + "code")[2]

Upvotes: 0

Views: 8643

Answers (2)

Rober
Rober

Reputation: 726

.Net framework provides a set of tools you can use to move over an XML file:

  1. XmlReader: this class reads xml files in hierarchical manner and only forward without cached.
  2. XmlWriter: this class writes in xml files only forward without cached.
  3. XmlDocument: it helps you to navigate and edit small documents as it's slower than XmlReader/Writer. It uses XmlNode objects to move through your document and perform changes (attributes). After editing your you can save. A nifty way to navigate is by using XPath (query language for xml).
  4. XPathNvigator: class offers an easy way to navigate through an XML document.

In your case, my recommendation is to implement a couple of methods one for iteration and one for location of a particular node with XmlReader and XPath respectively.

Update: the XML example is malformed here:

<legislation>d/legislation>

This shows you an example to read the file:

using System;
using System.Xml;

namespace XMLTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
                            <soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
                              <soap:Body>
                                <GetITARListResponse xmlns=""http://tempuri.org/"">
                                  <GetITARListResult>
                                    <ClassificationCode>
                                      <code>dsd</code>
                                      <description>toto</description>
                                      <legislation>d</legislation>
                                    </ClassificationCode>
                                    <ClassificationCode>
                                      <code>dsd</code>
                                      <description>tata</description>
                                      <legislation>dsd</legislation>
                                    </ClassificationCode>
                                    <ClassificationCode>
                                      <code>code2</code>
                                      <description>dsds</description>
                                      <legislation>dsd</legislation>
                                    </ClassificationCode>
                                  </GetITARListResult>
                                </GetITARListResponse>
                              </soap:Body>
                            </soap:Envelope>";

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);

            var items = doc.GetElementsByTagName("ClassificationCode");

            foreach (var item in items)
            {
                Console.WriteLine(((System.Xml.XmlElement)(item)).InnerText.ToString());
            }
            Console.ReadLine();
        }
    }
}
// OUTPUT
// dsdtotod
// dsdtatadsd
// code2dsdsdsd

Upvotes: 2

Volkan Paksoy
Volkan Paksoy

Reputation: 6937

Your code sample is returning the First item merely because you're calling First() method. In order to loop through all codes you can skip the call and you will get an IEnumerable. Then you can loop like this:

var codes = result.Descendants(XNamespace.Get("http://tempuri.org/") + "code");

foreach (var codeElement in codes)
{
    Console.WriteLine(codeElement.Value);
}
// prints:
// dsd
// dsd
// code2

To access them by index you can use ElementAt like this:

var someCode = codes.ElementAt(1);
Console.WriteLine(someCode.Value);  // prints dsd

Or you can filter by name like this:

var code2 = codes.Where(c => c.Value == "code2").First();
Console.WriteLine(code2.Value); // prints code2     

Upvotes: 1

Related Questions