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>
ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
VoiD HD
  • 699
  • 2
  • 8
  • 18
  • 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,803
  • 1
  • 23
  • 25
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
  • 56,650
  • 48
  • 196
  • 243
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
  • 33,250
  • 2
  • 15
  • 20
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
  • 28,294
  • 6
  • 61
  • 84