• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 867
  • Last Modified:

problem with reading an XML file using C#

Hi EE,
i have the following xml structure and I need to extract the //feed/entry/id out although I can never get it working when the
xmlns namespace is included.

Im trying to achieve the desired outcome using the c# code in the snippet section although my attemps fail.

The code needs to extract the id node, therefore I need to collect the following data out of the xml file.

here
there
test

XML structure here
=================


<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
      <title>xx</title>
      <subtitle>xx</subtitle>
      <link rel="self" type="application/atom+xml" href="xxx"/>
      <updated>2009-02-13T17:51:40.225Z</updated>
      <author>
            <name>aaa</name>
            <uri>nnn</uri>
            <email>ccc</email>
      </author>
      <id>asd</id>
      <icon>tgb</icon>
      <rights>qqqq</rights>
      <entry>
            <title>aaaa</title>
            <link href="xxxx"/>
            <id>here</id>
            <summary/>
            <updated>dffdfsddfs</updated>
            <content>pppp</content>
      </entry>
      <entry>
            <title>aaaa</title>
            <link href="xxxx"/>
            <id>there</id>
            <summary/>
            <updated>dffdfsddfs</updated>
            <content>pppp</content>
      </entry>
      <entry>
            <title>aaaa</title>
            <link href="xxxx"/>
            <id>test</id>
            <summary/>
            <updated>dffdfsddfs</updated>
            <content>pppp</content>
      </entry>
</feed>


please advise why this code isnt working.  Many thanks!
// this code is not using Linq although I have mentioned it.  I would like to get this working, with or without Linq.
 
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(@"c:\atomtestfile.xml");
XmlNodeList node = xmldoc.SelectNodes("//feed/entry/id");
 
 
// with this code, the node.Count equals 0 ???

Open in new window

0
jimbona27
Asked:
jimbona27
  • 5
  • 3
2 Solutions
 
jimbona27Author Commented:
thanks for this, although using the code below the nodeList is empty so the foreach never gets reached?
what am I doing wrong?
Thanks!

            List<RecordTypeXml> results = new List<RecordTypeXml>();
            XmlDocument xml = new XmlDocument();
            xml.Load(@"C:\atom.xml");
            XmlNamespaceManager ns = new XmlNamespaceManager(xml.NameTable);
            ns.AddNamespace("y", "http://schemas.microsoft.com/office/project/server/webservices/ProjectDataSet/");
            XmlNodeList nodeList = xml.SelectNodes("//feed/entry/id", ns);
            
            foreach (XmlNode test in nodeList)
            {
                // never gets reached?
            }

Open in new window

0
 
jimbona27Author Commented:
i have tried changing the string to this as well although nodeList is still empty:

XmlNodeList nodeList = xml.SelectNodes("//y:feed/y:entry/y:id", ns);
0
Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

 
abelCommented:
This will do what you want. Make the namespace specific, and use the specific namespace in the selectnodes statement. Microsoft is a bit tricky and non-standard when it comes to dealing with namespaces.

Note that your xpath expression starts with "//". That will traverse every single node of the XML and is quite costly. Since you know it is the root element, you can just as well specify with "/", which means "start from root".

The code below shows 3 hits.

XmlDocument xmldoc = new XmlDocument();
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmldoc.NameTable);
nsMgr.AddNamespace("a", "http://www.w3.org/2005/Atom");
xmldoc.Load("data/Q24168756.xml");
XmlNodeList node = xmldoc.SelectNodes("/a:feed/a:entry/a:id", nsMgr);

Open in new window

0
 
abelCommented:
The thing is, with namespaces, that they are helpers to avoid collisions. A namespace must match exactly, the URL does not have to exist (no parser in the world will physically look at the location), but should be unique (which is why you so often see url-style names as namespaces).

The prefix must, unfortunately, always be repeated. It should be possible to use the default namespace, but Microsoft made that property read-only. You can work around that, but that's quite some more work. In XSLT 2.0 / XPath 2.0 there are many easier ways to do all this, but Microsoft has yet to come with an implementation (but you may try Saxon.Net though).

If you are uncertain about whether you got your namespace correct, you can use the following style of coding, which is highly unreadable but has the advantage of not having to worry about namespace correctness:

XmlNodeList node = xmldoc.SelectNodes("/*[local-name() = 'feed']/*[local-name() = 'entry']/*[local-name() = 'id']", nsMgr);
0
 
jimbona27Author Commented:
thank you, this seems to work now.  Can you tell me how to use this value in the app.config as this technique of {} brackets in the config is new to me.
I need to use this key from the config file to complete this problem.  I just need a tutorial link or something simple to appreciate what this means.
Many thanks,


    <add key="xx" value="/{0}/test/{1}/"/>
0
 
jimbona27Author Commented:
any ideas?
Thanks!
0
 
abelCommented:
Just in general, accolades can be used as a replacement for string format operations. Apparently, some application that needs those values also does some string formatting. How this works is, amongst other places, explained here: http://blog.stevex.net/index.php/string-formatting-in-csharp/

Note that this has nothing to do with the app.config, but it has everything to do with strings and you can use the same curly brackets in your normal string formatting.
0
 
jimbona27Author Commented:
thanks
0

Featured Post

Free learning courses: Active Directory Deep Dive

Get a firm grasp on your IT environment when you learn Active Directory best practices with Veeam! Watch all, or choose any amount, of this three-part webinar series to improve your skills. From the basics to virtualization and backup, we got you covered.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now