Click here to Skip to main content
15,400,282 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I am trying to read data from an API xml file (URL). The link works and shows the raw data but When using the Repeater control in the page below, nothing is shown The attribute (ns2:description) I am trying to access it an example so I should be able to access any attribute in the file. Can anyone advise on how to correct this ?

XML
<%@ Page Language="VB" ContentType="text/html" ResponseEncoding="iso-8859-1" Debug="true" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System" %>
<%@ import Namespace="System.IO" %>
<%@ import Namespace="System.Xml" %>
<%@ import Namespace="System.Net.HttpWebResponse" %>


<Script runat="server">



sub Page_Load
if Not Page.IsPostBack then


 Dim doc  as XmlDocument = new XmlDocument()
doc.Load("http://api.tradedoubler.com/1.0/products.xml?token=96CC0E0A10851500F10431D64EC5585BFC8597DF")
Dim nodes As XmlNodeList = doc.SelectNodes("products/product")
rpMyRepeater.DataSource = nodes
rpMyRepeater.DataBind()

end if
end sub


</script>


<html>
<body>
<asp:repeater id="rpMyRepeater" runat="server">
<HeaderTemplate>
   <Table border="0">
</HeaderTemplate>
   <ItemTemplate>
   <tr style="background-color:FFECD8">
      <td>




<![CDATA[<%# DirectCast(Container.DataItem, System.Xml.XmlNode).Attributes("ns2:description").Value %>]]>


      </td>
   </tr>
   </ItemTemplate>
   <FooterTemplate>
      </Table>
   </FooterTemplate>
</asp:repeater>
Posted
Comments
Richard Deeming 24-Aug-15 16:51pm
   
You forgot to include the XML file you're reading.
hm9 24-Aug-15 16:52pm
   
Its in the URL link

http://api.tradedoubler.com/1.0/products.xml?token=96CC0E0A10851500F10431D64EC5585BFC8597DF
Maciej Los 24-Aug-15 17:04pm
   
Have you tried to debug programme? Please, use "Reply" widget, if you want to notify me about your reply.
George Swan 25-Aug-15 2:26am
   
This looks like a namespace problem. If namespaces are defined in the xml, you need to use a XmlNamespaceManager to access the nodes effectively. See
https://support.microsoft.com/en-us/kb/318545
hm9 25-Aug-15 7:48am
   
Would it be possible to adapt my code to work with xmlnamespaceManager. I don't know c# only VB.net.
ZurdoDev 25-Aug-15 7:57am
   
C# and VB.Net are almost the same thing. If you know how to do something in VB, it should be easy to convert to C#.

1 solution

As George said, this is a namespace issue. Unfortunately, the XmlDocument class doesn't make it easy to work with XML namespaces, and particularly with documents which have a default namespace. You have to create an XmlNamespaceManager, explicitly add the namespaces, and give the default namespace a prefix.

Also, looking at the source document, the ns2:description that you're trying to retrieve is an element, so you won't be able to find it in the Attributes collection.

Since you need the XmlNamespaceManager to retrieve the child elements, the simplest option is probably to project the nodes to a custom type in the Page_Load method.

VB.NET
Dim doc As New XmlDocument()
doc.Load("http://api.tradedoubler.com/1.0/products.xml?token=96CC0E0A10851500F10431D64EC5585BFC8597DF")

Dim nsManager As New XmlNamespaceManager(doc.NameTable)
nsManager.AddNamespace("ns1", "urn:com:tradedoubler:pf:model:xml:output")
nsManager.AddNamespace("ns2", "urn:com:tradedoubler:pf:model:xml:common")

Dim nodes As XmlNodeList = doc.SelectNodes("//ns1:products/ns1:product", nsManager)

Dim dataSource As IEnumerable 
dataSource = From node As XmlNode in nodes
             Select Name = node.SelectSingleNode("ns2:name", nsManager).InnerText, _
             Description = node.SelectSingleNode("ns2:description", nsManager).InnerText, _
             Image = node.SelectSingleNode("ns2:productImage", nsManager).InnerText

rpMyRepeater.DataSource = dataSource
rpMyRepeater.DataBind()

ASP.NET
<asp:repeater id="rpMyRepeater" runat="server">
<HeaderTemplate>
    <table border="0">
</HeaderTemplate>
<ItemTemplate>
    <tr style="background-color:FFECD8">
        <td>
            <%# Eval("Name") %>
        </td>
        <td>
            <%# Eval("Description") %>
        </td>
        <td>
            <asp:image runat="server"
                ImageUrl='<%# Eval("Image") %>'
            />
        </td>
    </tr>
</ItemTemplate>
<FooterTemplate>
    </table>
</FooterTemplate>
</asp:repeater>


NB: To use the LINQ query, you might need to import the System.Linq namespace, if it's not already imported in your web.config file:
ASP.NET
<%@ Import Namespace="System.Linq" %>
   
v2
Comments
Maciej Los 25-Aug-15 8:38am
   
+5!
hm9 25-Aug-15 9:21am
   
Thanks Richard. I assume there is a typo in the line below?:

dataSource = From node As XmlNode in nodes
Richard Deeming 25-Aug-15 9:24am
   
No, that's a LINQ query.
Introduction to LINQ in Visual Basic[^]
hm9 25-Aug-15 9:33am
   
Its just I get the error: Name 'From' is not declared.
Richard Deeming 25-Aug-15 9:34am
   
What version of .NET are you using?
hm9 25-Aug-15 9:55am
   
3.5 I am using it on a local server. Does it work on yours?
Richard Deeming 25-Aug-15 10:12am
   
It works for me in 3.5, with a couple of small changes:

* You'll need to add the line continuation character to the end of the lines in the LINQ query;
* The "image" element should actually be "productImage";
* You might need to import the "System.Linq" namespace, if it's not already in your web.config file;

I'll update the answer with the changes.
hm9 25-Aug-15 10:27am
   
Ok I tried that but still the same error. One thing may be is the ns1 namespace. This isn't on the xml ? but as you stated, it works on your environment
Richard Deeming 25-Aug-15 10:30am
   
As I mentioned in the answer, the XmlDocument class doesn't work well with default namespaces. You have to define the namespace with a prefix, and use that prefix in any queries.

In this case, ns1:product refers to the product element in the namespace with the prefix ns1. The XmlNamespaceManager maps this prefix to the namespace URN "urn:com:tradedoubler:pf:model:xml:output", which is the default namespace on the document you've loaded.
Richard Deeming 25-Aug-15 10:33am
   
If you're still getting a "From is not declared" compiler error, then you're not using .NET 3.5; check your web.config file for the required settings. In particular, look for the system.codedom/compilers section.

Dissecting ASP.NET Version 3.5's Web.config File[^]
hm9 25-Aug-15 11:50am
   
You are right it wasn't using 3.5. Changed it and it worked. Thanks again
hm9 4-Sep-15 16:08pm
   
Hi Richard, Just realised I also want to retrieve the values of price, productUrl but these are under offers/offer namespace. how do I achieve this? I tried adding it to the XmlNodeList but then i will miss the other elements directly under product. Thanks
Richard Deeming 14-Sep-15 8:06am
   
You'd need to use the ns1 prefix for elements which are under the default namespace:

ProductUrl = node.SelectSingleNode("ns1:offers/ns1:offer/ns2:productUrl", nsManager).InnerText, _
Price = node.SelectSingleNode("ns1:offers/ns1:offer/ns1:priceHistory/ns2:price", nsManager).InnerText
George Swan 26-Aug-15 2:44am
   
Can you please mark this problem as solved? As, it seems to me, that Richard has produced an excellent solution.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900