0

I have an XML file that contains multiple URLs for different image file sizes, and I'm trying to get a single url to load into a picture box. My issue is that the child nodes are named similarly, and the parent nodes are named similarly as well. For example, I want to pull the first medium image (ending in SL160_.jpg). See below for XML code

<Items>
<SmallImage>
    <URL>http://ecx.images-amazon.com/images/I/51TAL%2Bn7AqL._SL75_.jpg</URL>
</SmallImage>
<MediumImage>
    <URL>http://ecx.images-amazon.com/images/I/51TAL%2Bn7AqL._SL160_.jpg</URL>
</MediumImage>
<LargeImage>
    <URL>http://ecx.images-amazon.com/images/I/51TAL%2Bn7AqL.jpg</URL> 
</LargeImage>
<MediumImage>
    <URL>http://ecx.images-amazon.com/images/I/51TAL%2Bn7AqL._SL162_.jpg</URL> 
</MediumImage>
<LargeImage>
    <URL>http://ecx.images-amazon.com/images/I/51TAL%2Bn7AqL.jpg</URL> 
</LargeImage>
</Items>

I've tried using GetElementsByTag, as well as trying to call something like doc.SelectSingleNode("LargeImage").SelectSingleNode("URL").InnerText, and GetElementByID. All of these have given me an Object set to null reference exception.

What can I do to specify that I want the url from the first found MediumImage node?

Chris Hobbs
  • 745
  • 2
  • 9
  • 27
  • Please post [*minimal but complete*](http://stackoverflow.com/help/mcve) example demonstrating the problem. Without that I can only guess, maybe : `doc.SelectSingleNode("//MediumImage/URL").InnerText` – har07 Jul 16 '15 at 03:26
  • Your codes says `"LargeImage"`, but the last sentence in the question ask for `MediumImage` node? – har07 Jul 16 '15 at 03:30
  • I was trying for either/or, and accidentally left `LargeImage` instead of `MediumImage` - and I'll make sure to post a complete example in the future, but I had tried things such as `doc.SelectSingleNode("//LargeImage/URL").InnerText` and `doc.SelectSingleNode("/LargeImage/URL").InnerText` and `doc.SelectSingleNode("LargeImage/URL").InnerText` and others. I'm going to try SkyFangs answer below and I'll let you know how it goes! – Chris Hobbs Jul 16 '15 at 03:32
  • 1
    I suspect your XML has default namespace (something like `xmlns="..."`), no? – har07 Jul 16 '15 at 04:15
  • Yeah, I removed all the excess to get a minimized XML code since the original was a couple hundred lines long. – Chris Hobbs Jul 16 '15 at 04:20
  • If the actual XML has default namespace, than there is the core problem. Try something like `doc.SelectSingleNode("//d:LargeImage/d:URL", nsManager).InnerText` : 1. http://stackoverflow.com/questions/26179677/selectnodes-does-not-return-the-child-values/26179849#26179849, 2. http://stackoverflow.com/questions/31084447/xmlns-attribute-wont-let-me-parse/31084480#31084480 – har07 Jul 16 '15 at 04:26

3 Answers3

0

Use LinqToXML,It is rather simple

string xml = @"<Items>
<SmallImage>
<URL>http://ecx.images-amazon.com/images/I/51TAL%2Bn7AqL._SL75_.jpg</URL>
</SmallImage>
<MediumImage>
<URL>http://ecx.images-amazon.com/images/I/51TAL%2Bn7AqL.01_SL160_.jpg</URL>
</MediumImage>
<LargeImage>
<URL>http://ecx.images-amazon.com/images/I/51TAL%2Bn7AqL.jpg</URL> 
</LargeImage>
<MediumImage>
<URL>http://ecx.images-amazon.com/images/I/51TAL%2Bn7AqL.02_SL162_.jpg</URL> 
</MediumImage>
<LargeImage>
<URL>http://ecx.images-amazon.com/images/I/51TAL%2Bn7AqL.jpg</URL> 
</LargeImage>
</Items>";
XElement root = XElement.Parse(xml);
var ele = root.Elements("MediumImage").Where(e => e.Element("URL").Value.EndsWith("SL160_.jpg")).FirstOrDefault();
Console.WriteLine(ele);
Sky Fang
  • 1,101
  • 6
  • 6
  • What if the ending doesn't matter? It could end in literally anything, so I'm looking for only the URL under the first element named `MediumImage` -- is there something like `root.Elements("MediumImage").Element("URL").Value.FirstOrDefault();` that I'd be able to use to access it? – Chris Hobbs Jul 16 '15 at 03:36
  • Please pardon my poor english,but `ele` is already the `MediumImage` node you want,you just need to check is it null,if not null,you can use `ele.Element("URL").Value` to get the url – Sky Fang Jul 16 '15 at 03:44
  • And if you don't know which type image you want and you just know what endwith,you also can use `root.Elements()` to replace `root.Elements("MediumImage")` – Sky Fang Jul 16 '15 at 03:46
0

In addition to Sky Fang's answer, I think the OP wants this:

var firstMedImg = root.Elements("MediumImage").First();
var imgUrl = firstMedImg.Element("URL").Value;
Ken Hung
  • 190
  • 6
0
        XmlDocument doc = new XmlDocument();

        // PATH TO YOUR DOCUMENT
        doc.Load("daco.xml");

        // Select LIST ALL ELEMENTS SmallImage,MediumImage,LargeImage
        XmlNodeList listOfAllImageElements = doc.SelectNodes("/Items/*");

        foreach (XmlNode imageElement in listOfAllImageElements)
        {
            // Select URL ELEMENT
            XmlNode urlElement= node.SelectSingleNode("URL");
            System.Console.WriteLine(urlElement.InnerText);
        }

        Console.ReadLine();

If you want to select multiple url's

        XmlDocument doc = new XmlDocument();

        // PATH TO YOUR DOCUMENT
        doc.Load("daco.xml");

        // Select LIST ALL ELEMENTS SmallImage,MediumImage,LargeImage
        XmlNodeList listOfAllImageElements = doc.SelectNodes("/Items/*");

        foreach (XmlNode imageElement in listOfAllImageElements)
        {
            // Select URL's ELEMENTs
            XmlNodeList listOfAllUrlElements = imageElement.SelectNodes("URL");
            foreach (XmlNode urlElement in listOfAllUrlElements)
            {
                System.Console.WriteLine(urlElement.InnerText);
            }
        }

        Console.ReadLine();

if you have specific namespace in your xml file

        XmlDocument doc = new XmlDocument();
        doc.Load("doc.xml");

        XmlNamespaceManager man = new XmlNamespaceManager(doc.NameTable);
        // reaplace http://schemas.microsoft.com/vs/2009/dgml with your namespace
        man.AddNamespace("x", "http://schemas.microsoft.com/vs/2009/dgml");

        // next you have to use x: in your path like this 
        XmlNodeList node = doc.SelectNodes("/x:Items/x:*, man);
Sourness
  • 23
  • 1
  • 6