1

I have been working with C# and would like to know what the easiest way to find each id of <lib> would be?, I really am new to C# itself and especially XML so I would appreciate some help.

C#

var xmlData = client.DownloadString(figureMapUrl);
var doc = XDocument.Parse(xmlData);

XML:

<map>
    <lib id="myid1" revision="1">
        <part id="2732" type="ch"/>
        <part id="2732" type="ls"/>
        <part id="2732" type="rs"/>
        <part id="2733" type="ch"/>
    </lib>
    <lib id="myid2" revision="2">
        <part id="2732" type="ch"/>
        <part id="2732" type="ls"/>
        <part id="2732" type="rs"/>
        <part id="2733" type="ch"/>
    </lib>
</map>
Chris
  • 112,704
  • 77
  • 249
  • 231
VoiD HD
  • 519
  • 2
  • 6
  • 17
  • To parse this into a more manageable manner you may want to deserialize into classes, but this would be based on what you are trying to do. – vipersassassin Dec 19 '16 at 22:52
  • I would agree with the comment about deserializing into an object. Also, your example gives two different entities that have an "id" attribute. Is a single big array with all of the "id" values inside it what you're after? – Aaron Averett Dec 19 '16 at 22:54
  • Yes, that is what I am after – VoiD HD Dec 19 '16 at 22:56
  • 1
    "easiest" is very much opinion-based. Some people prefer LINQ to XML; others a more DOM based implementation; yet others like SAX. Parsing the XML is already answered [here](http://stackoverflow.com/q/55828/215552). – Heretic Monkey Dec 19 '16 at 23:12

4 Answers4

1

A little more XML based approach would look like this. No need for POCO here.

XmlDocument xml = new XmlDocument();
xml.loadXML( strXMLString );
foreach( XmlElement ndLib in xml.selectNodes( "//lib" ) ) {
    string strID = ndLib.getAttribute( "id" );
    string strRevision = ndLib.getAttribute( "revision" );
}
William Walseth
  • 2,680
  • 1
  • 23
  • 21
0

You are looking for LINQ to XML. I didn't try this code myself, but from the top of my mind it would be something like:

// getting first level ids using LINQ to XML
var libIds = from lib in doc.Descendants("lib")
select new { id = lib.Attribute("id").Value };

// getting second level ids using LINQ to XML
var partIds = from lib in doc.Descendants("lib")
from part in lib.Descendants("part")
select new { value = part .Attribute("id").Value };

Now libIds and partIds are IEnumerable<string>. You can do a .ToList() to turn them into lists.

EDIT

This is how you iterate the ids:

foreach(var id in partIds) Console.WriteLine(id);
Andre Pena
  • 52,662
  • 43
  • 183
  • 224
0

Try xml linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            var results = doc.Descendants("lib").Select(x => new
            {
                id = (string)x.Attribute("id"),
                revision = (int)x.Attribute("revision"),
                parts = x.Elements("part").Select(y => new
                {
                    id = (int)y.Attribute("id"),
                    type = (string)y.Attribute("type")
                }).ToList()
            }).ToList();

            foreach (string id in results.Select(x => x.id).ToArray())
            {
            }

            foreach (var part in results.Select(x => x.parts))
            {
                foreach (int id in part.Select(y => y.id).ToArray())
                {
                }
            }
        }
    }
}
jdweng
  • 29,955
  • 2
  • 14
  • 18
0

Using LINQ to XML, you could do the following:

var xmlData = client.DownloadString(figureMapUrl);
var doc = XDocument.Parse(xmlData);

var idList = doc.Descendants("lib").Select(el => el.Attribute("id").Value).Union(
             doc.Descendants("part").Select(el => el.Attribute("id").Value))
             .ToList();

Extra: if you want to avoid the repetition:

var idList = doc.Descendants("lib").Select(getId).Union(
             doc.Descendants("part").Select(getId))
             .ToList();

string getId(XElement el) => el.Attribute("id").Value;

to loop over this you could do a regular for-loop:

foreach(var id in idList)
{
    // Do something with ID here
}

or alternatively, you could use ForEachand eliminate the variable altogether:

doc.Descendants("lib").Select(getId).Union(
doc.Descendants("part").Select(getId))
   .ToList()
   .ForEach(id => {
      // Do something with id here
   });
Kenneth
  • 27,326
  • 6
  • 58
  • 82