locked
Google Base XML Consumption C# & Razor RRS feed

  • Question

  • User439975351 posted

    Hi All,

    I'm trying to consume an xml feed based on the Google Base namespace. I keep getting an error regarding the g: on nodes.

    Heres an example of the document:

    <?xml version="1.0" encoding="UTF-8"?>
    <feed xmlns="http://www.w3.org/2005/Atom" xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0">
      <title>Feed Title</title>
      <link rel="self" href="http://www.mydomain.local"/>
      <author>
        <name>My Google Base Feed</name>
      </author>
      <id>tag:mydomain.local,2013-05-05</id>
    
      <updated>2013-05-05T11:50:54Z</updated>
      <entry>
        <title>First Items Title</title>
        <summary><![CDATA[Text summary of item lisitng]]></summary>
        <id>ITD123</id>
        <g:image_link>exterior.jpg</g:image_link>
        <g:image_link>lounge.JPG</g:image_link>
        <g:image_link>kitchen.JPG</g:image_link>
        <g:image_link>bed1.JPG</g:image_link>
        <link href="http://mydomain.local/" />
        <g:location>London</g:location>
        <g:make>Ford</g:make>
        <g:model>Focus</g:model>
        <g:price>4995</g:price>
        <g:year>2012</g:year>
        <g:bedrooms>2</g:bedrooms>
        <c:type type="string">Hatchback</c:type>
        <g:condition>Second Hand</g:condition>
        <c:width>6'</c:width>
        <c:length>16'</c:length>
        <c:age></c:age>
        <c:condition>Excellent</c:condition>
        <c:exdisplay>False</c:exdisplay>   
          <c:regionName><![CDATA[London]]></c:regionName>
        <c:Postcode>EC1V</c:Postcode>    
      </entry>


    Can any one suggest the best tool to get this data out? (So that I can store it in a SQL Db).

    Thanks for any help :)

    Jus

    Tuesday, May 7, 2013 5:55 AM

Answers

  • User-821857111 posted

    The  g: is a namespace prefix. You need to concatenate that with the XElement name:

    var xml = XDocument.Load(location_of_file);
    var imageLink = "";
    var g = xml.Root.GetNamespaceOfPrefix("g");
    var image_link = xml.Descendants(g + "image_link").FirstOrDefault();
    if (image_link != null) {
        imageLink = image_link.Value;
    }



    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, May 7, 2013 7:16 AM
  • User-821857111 posted
    var feed = XDocument.Load(url);
    XNamespace xmlns = "http://www.w3.org/2005/Atom";
    
    var g = feed.Root.GetNamespaceOfPrefix("g");
    var c = feed.Root.GetNamespaceOfPrefix("c");
    
    var items = feed.Descendants(xmlns + "entry").Select(item => new {
        Title = item.Element(xmlns + "title").Value,
        Summary = item.Element(xmlns + "summary").Value,
        Link = item.Element(xmlns + "link").FirstAttribute.Value,
        Location = item.Element(g + "location").Value,
        Make = item.Element(g + "make").Value,
        Model = item.Element(g + "model").Value,
        Condition = item.Element(c + "condition").Value,
        Type = item.Element(c + "type").Value,
        Images = item.Elements(g + "image_link").Select(el => el.Value)
    });

    The Images property is actually a collection of strings. You will need to iterate that to get at each one:

    foreach (var item in items) {
        //you can get the Title, Summary etc here
        
        foreach (var image in item.Images) {
            //You can get at each image here
        }
    }



    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, May 7, 2013 2:41 PM

All replies

  • User-821857111 posted

    The  g: is a namespace prefix. You need to concatenate that with the XElement name:

    var xml = XDocument.Load(location_of_file);
    var imageLink = "";
    var g = xml.Root.GetNamespaceOfPrefix("g");
    var image_link = xml.Descendants(g + "image_link").FirstOrDefault();
    if (image_link != null) {
        imageLink = image_link.Value;
    }



    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, May 7, 2013 7:16 AM
  • User439975351 posted

    Thanks Mike, just tried that and am making some progress! :)

    Do I need to follow the same process for all of g elements or is there a way to map all of them in one statement?

    Also I have multiple image links, could you suggest the best way to iterate through these at all?

    Kind regards,

    Jus

    Tuesday, May 7, 2013 7:39 AM
  • User-821857111 posted

    If you have multiple nodes with the same name, you can get them in a collection:

    var image_links = xml.Descendants(g + "image_link");
    if (image_links.Any()) {
        foreach (var item in image_links) {
            //do something with item.Value
        }
    }

    You might be able to create a custom class that maps to the XElement names that you can get from the XML and then use reflection to marry up XElement names with public properties on your custom object. Something like this: http://stackoverflow.com/questions/15491244/importing-xml-to-objects-recursively

    Tuesday, May 7, 2013 8:07 AM
  • User439975351 posted

    Thanks Mike, think I'm nearly there now :)

    Tuesday, May 7, 2013 8:36 AM
  • User439975351 posted

    Mike, I wonder if you could help one final time!

    I have put this together (probably incorrectly) it gets the results that I want but I'm not sure how to pull the image multiples into the LInq to XML Select?

      var feed = XDocument.Load(url);
        XNamespace xmlns = "http://www.w3.org/2005/Atom";
        
        //Set g: & c: concats
        var g = feed.Root.GetNamespaceOfPrefix("g");
        var c = feed.Root.GetNamespaceOfPrefix("c");    
        
    
         //Add all images to list
         List<string> imgList = new List<string>();     
         var count = 0;
    
         foreach (var item in feed.Descendants(xmlns + "entry"))
         {
             if (item != null)
             {
                 count = item.Descendants(g + "image_link").Count();
                 imgList.Clear();
    
                 foreach (var img in item.Descendants(g + "image_link"))
                 {
    
                     imgList.Add(img.Value);
                 }
    
             }
         }
        
        var items = feed.Descendants(xmlns + "entry").Select(item => new
        {
            Title = item.Element(xmlns + "title").Value,
            Summary = item.Element(xmlns + "summary").Value,
            Link = item.Element(xmlns + "link").FirstAttribute,
            Location = item.Element(g + "location").Value,
            Make = item.Element(g + "make").Value,
            Model = item.Element(g + "model").Value,      
            Condition = item.Element(c + "condition").Value,        
            Type = item.Element(c + "type").Value, 
            Image = item.Element(g + "image_link").Value
             
        });



    Tuesday, May 7, 2013 10:29 AM
  • User-821857111 posted
    var feed = XDocument.Load(url);
    XNamespace xmlns = "http://www.w3.org/2005/Atom";
    
    var g = feed.Root.GetNamespaceOfPrefix("g");
    var c = feed.Root.GetNamespaceOfPrefix("c");
    
    var items = feed.Descendants(xmlns + "entry").Select(item => new {
        Title = item.Element(xmlns + "title").Value,
        Summary = item.Element(xmlns + "summary").Value,
        Link = item.Element(xmlns + "link").FirstAttribute.Value,
        Location = item.Element(g + "location").Value,
        Make = item.Element(g + "make").Value,
        Model = item.Element(g + "model").Value,
        Condition = item.Element(c + "condition").Value,
        Type = item.Element(c + "type").Value,
        Images = item.Elements(g + "image_link").Select(el => el.Value)
    });

    The Images property is actually a collection of strings. You will need to iterate that to get at each one:

    foreach (var item in items) {
        //you can get the Title, Summary etc here
        
        foreach (var image in item.Images) {
            //You can get at each image here
        }
    }



    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, May 7, 2013 2:41 PM
  • User439975351 posted

    Mike, Thank you for taking the time to look at this. Thats got it. Very much appreciated.

    All the best,

    Jus

    Tuesday, May 7, 2013 5:47 PM