tags:

views:

70

answers:

3

i'm dramatically confused with reading XML...I feel in way over my head.

currently, using the XML below as an input source, i'm able to get all of the names by using

XmlNodeList name = xDoc.GetElementsByTagName("Name");
int i;
for (i=0; i < sent.Count; i++)
{
    MessageBox.Show(name[i].InnerText);
}

When I try to do the same for id, however, it also returns line 2 "someID".

I basically need to just rip all of the InsuredListMember and save them, any suggestions? i've been staring at xpath tutorials for a good week now and they make absolutely zero sense is why i fell back on getelementsbytagname

XML:

<?xml version="1.0" encoding="UTF-8"?>
    <feed xmlns="http://www.w3.org/2005/Atom"&gt;
      <id>someID</id>
      <title type="text">Title</title>
      <author>
        <name>XML Author</name>
      </author>
      <updated>2010-10-25T20:05:30.267Z</updated>
      <link href="currentURL"></link>
      <link href="nextURL"></link>
      <entry>
        <id>Drivers License Number</id>
        <content type="application/vnd.ctct+xml">
          <InsuredListMember xmlns="http://strange.com/ns/1.0/" id="drivers license number">
            <HomeAddress>123 anystreet</HomeAddress>
            <Name>doe, somegal</Name>
          </InsuredListMember>
        </content>
      </entry>
      <entry>
        <id>Drivers License Number</id>
        <content type="application/vnd.ctct+xml">
          <InsuredListMember xmlns="http://strange.com/ns/1.0/" id="drivers license number">
            <HomeAddress>321 anystreet</HomeAddress>
            <Name>doe, someguy</Name>
          </InsuredListMember>
        </content>
      </entry>
    </feed>
+2  A: 

You could try

XmlNodeList xnlInsuredListMembers = xDoc.SelectNodes("//InsuredListMember");
foreach (XmlNode xnMember in xnlInsuredListMembers)
{
    XmlNode xnHomeAddress = xnMember.SelectSingleNode("HomeAddress");
    string sHomeAddress = xnHomeAddress.InnerText;

    XmlNode xnName = xnMember.SelectSingleNode("Name");
    string sName = xnName.InnerText;

    saveMember(sName, sHomeAddress);
}

or something like that. Yes, this is XPath, but I think that's just the cleaner way.

Edit:

Alright, as I said, XML namespaces are annoying (at one time in the past even causing me to remove all xmlns attributes from the XML source because I had no idea how to handle them), but I just figured it out.

You need an XmlNamespaceManager and let it know about the namespace used (for some reason you only need the one in the InsuredListMember tag but not the one in the feed tag).

XmlNamespaceManager xnsmgr = new XmlNamespaceManager(xDoc.NameTable);
xnsmgr.AddNamespace("ns", "http://strange.com/ns/1.0/");

XmlNodeList xnlInsuredListMembers = xDoc.SelectNodes("//ns:InsuredListMember", xnsmgr);
foreach (XmlNode xnMember in xnlInsuredListMembers)
{
    XmlNode xnHomeAddress = xnMember.SelectSingleNode("ns:HomeAddress", xnsmgr);
    string sHomeAddress = xnHomeAddress.InnerText;

    XmlNode xnName = xnMember.SelectSingleNode("ns:Name", xnsmgr);
    string sName = xnName.InnerText;

    saveMember(sName, sHomeAddress);
}

That's the way it works.

GCATNM
Agreed. Looks obvious and is easy to understand.
Pat
That's the issue I ran into with Xpath, seems logical enough, but //InsuredListMember doesn't actually select anything. If I do an addnamespace("ns", "http://strange.com/ns/1.0/") and use //ns:HomeAddress I can pull just the home address, but can't do a //ns.
Frank Hodgkins
Ah, damn, the namespace; those are annoying. What would you want to achieve with //ns ?
GCATNM
Just doing some testing, sorry i'm kind of scatter brained today. Following your example above, xnMember.SelectNode doesn't exist, assumed selectsinglenode was meant. upon execution i get no errors, but nothing is found/returned?
Frank Hodgkins
Yeah, I actually meant SelectSingleNode(); I corrected that and added the correct namespace handling.
GCATNM
A: 

Going with learning proper Xpath instead...greasy hacks just to get by are going to be detrimental in the long run. thanks all!

Frank Hodgkins
A: 

I recommend learning LINQ To XML. There is a mess of antiquated DOMs in .NET and LINQ improves on all of them so much I don't see a reason to learn them at this point. The following line retrieves the "InsuredListMember" nodes in LINQ:

var insuredListMembers = xDoc.Descendants("InsuredListMember");

xDoc in this case would be an XElement from the System.Xml.Linq namespace. And insuredListMembers would be an IEnumerable<XElement> that can be further queried, sorted or anything else an Enumerable can do. If you are just starting to use XML skip XPath. LINQ is the present and the future, for very good reasons.

Sorax