-2

I have a given XML file that I need to process. For the sake of argument, let's say I've already loaded it in as a string.

<?xml version="1.0" encoding="UTF-8" ?> 
<GROUP ID="_group_id" ORDERINFO="00000" TITLE="Group 1">
  <GROUP ID="_group_id_2" TITLE="Group 2">
    <LO ID="_id_code1" LANG="enUS" TYPE="_cust" TITLE="Title 1" /> 
    <LO ID="_id_code2" LANG="enUS" TYPE="_cust" TITLE="Title 2" /> 
  </GROUP>
  <GROUP ID="_group_id_3" TITLE="Group 3">
    <LO ID="_id_code1" LANG="enUS" TYPE="_cust" TITLE="Title 1" /> 
    <LO ID="_id_code2" LANG="enUS" TYPE="_cust" TITLE="Title 2" /> 
  </GROUP>
</GROUP>

There can be many LOs and many GROUPs in a given XML file. I've been trying various methods with no luck. I need something that will find the matching LO by ID to a given string and then allow me to retrieve the corresponding TYPE and TITLE into strings so that I may use them for processing.

I tried reading the file into an XmlDocument but once loaded I could not figure out how to find the appropriate elements.

Sorry for post prior to edit - some text got cut off

Dustin Kingen
  • 20,677
  • 7
  • 52
  • 92
user1366062
  • 163
  • 3
  • 16

5 Answers5

4

You can use XmlDocument or XDocument to parse the Xml.

Here is an example with XDocument:

Data class:

public class Lo
{
    public string Id { get; set; }
    public string Lang { get; set; }
    public string Type { get; set; }
    public string Title { get; set; }
}

Code:

var document = XDocument.Parse(data);

var value = "_id_code1";

IEnumerable<Lo> result = 
    document.XPathSelectElements(".//LO")
            .Where(x => x.Attribute("ID").Value == value)
            .Select(x =>
                new Lo
                {
                    Id = x.Attribute("ID").Value,
                    Lang = x.Attribute("LANG").Value,
                    Type = x.Attribute("TYPE").Value,
                    Title = x.Attribute("TITLE").Value
                });
Dustin Kingen
  • 20,677
  • 7
  • 52
  • 92
2

When loaded into a XmlDocument, you can use XPath to locate notes.

E.g:

XmlNode group = xmlDocument.SelectSingleNode("/GROUP/GROUP[@ID='_group_id_2']");

Or:

XmlNodeList groups = xmlDocument.SelectNodes("/GROUP/GROUP");
foreach(XmlNode group in groups)
{
    string id = group.Attributes["ID"].Value;

}

It is very easy. For a more complete walk through you should search the internet.

Casperah
  • 4,504
  • 1
  • 19
  • 13
  • I've been doing some researching on how to do this using XPath like you suggested, as I would prefer to use this as I may be constrained to .net 2.0 in this case. My issue is that I don't know how many GROUPs there may or may not be.. so I have tried writing a statement that skips all of the group stuff, but I get a null result every time: XmlNode group = xmlDocument.SelectSingleNode("//LO[ID=" + strcourseID + "]"); where strcourseID is the course ID I have stored in a string. – user1366062 Jun 19 '13 at 17:35
  • Got it sorted out. I used SelectSingleNode("//LO[@ID=\"" + strcourseID + "\"]"); and that solved the problem. Finicky syntax ;) – user1366062 Jun 19 '13 at 18:03
1

See the documentation:

codeape
  • 97,830
  • 24
  • 159
  • 188
0

It's better to cast XAtribute to string, then access its Value property (if some attribute not found, you will get null instead of exception). Also query syntax is more compact here

string id = "_id_code1";
XDocument xdoc = XDocument.Parse(xml);

var query = from lo in xdoc.Descendants("LO")
            where (string)lo.Attribute("ID") == id
            select new {
                Id = (string)lo.Attribute("ID"),
                Language = (string)lo.Attribute("LANG"),
                Type = (string)lo.Attribute("TYPE"),
                Title = (string)lo.Attribute("TITLE")
            };

This query will return sequence of anonymous objects with properties Id, Language, Type, Title. You can enumerate them with foreach.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
0

I did small test application for this, I included your xml as the string.

            var xmlMessage = @"keep your xml here, I removed due to formatting";
        var matchedElements = XDocument.Parse(xmlMessage).Descendants().Where(el => el.Name == "LO" && el.Attribute("ID").Value == "_id_code1");
        foreach (var el in matchedElements)
        {
            Console.WriteLine("ElementName : {0}\nID = {1}\nLANG = {2}\nTYPE = {3}\nTITLE = {4}\n"
                , el.Name.LocalName, el.Attribute("ID").Value, el.Attribute("LANG").Value, el.Attribute("TYPE").Value, el.Attribute("TITLE").Value);

         }

This would help you to fetch all LO elements having the ID "_id_code" irrespective of the GROUP element. If you need to consider the group, replace the second line code with this:

var matchedElements = XDocument.Parse(xmlMessage).Descendants().Where(el => el.Parent != null && el.Parent.Attribute("ID").Value == "_group_id_2" && el.Name == "LO" && el.Attribute("ID").Value == "_id_code1");

Here, I'm checking for the "_group_id_2", you can replace with your group id.

The required namespaces:

using System.Linq;
using System.Xml;
using System.Xml.Linq;
Karthik D V
  • 906
  • 1
  • 11
  • 19