Click here to Skip to main content
13,044,467 members (120,350 online)
Rate this:
 
Please Sign up or sign in to vote.
See more:
Hi,

I have an XML file, and I need to extract some of its contents, however the file is non-standard XML and I am not familiar with XPath. I have tried researching on the internet however the presented solutions did not seem to work.

Basically the XML content of the file is as follows:

<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<URLBase>http://192.168.1.254:8000</URLBase>
<device>
<deviceType>
urn:schemas-upnp-org:device:InternetGatewayDevice:1
</deviceType>
<friendlyName>Name and Version here...</friendlyName>
<manufacturer>Name here...</manufacturer>
<manufacturerURL>Website here...</manufacturerURL>
<modelDescription>Internet Gateway Device</modelDescription>
<modelName>Model here...</modelName>
<modelNumber>Number here...</modelNumber>
<modelURL>URL here...</modelURL>
<serialNumber>Serial Number here...</serialNumber>
<UDN>uuid:UPnP_Name and MAC here...</UDN>
<presentationURL>/</presentationURL>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:Layer3Forwarding:1</serviceType>
<serviceId>urn:upnp-org:serviceId:L3Forwarding1</serviceId>
<controlURL>/IGD/upnp/control/igd/layer3f</controlURL>
<eventSubURL>/IGD/upnp/event/igd/layer3f</eventSubURL>
<SCPDURL>/IGD/upnp/Layer3Forwarding.xml</SCPDURL>
</service>
</serviceList>
</device>
</root>


I need to extract the text in the deviceType and serviceType tags. I have tried using the "/deviceType" tag but it extracts nothing, while the "//*" seems to retrieve all the elements in the document, however that is not what I had in mind. Sorry to be bothering with possibly a very easy question, but I can't get it to work and I'm not sure which aspect I'm doing wrong. Any code snippets of this text extraction are greatly appreciated.

P.S. In the original XML document, there are multiple deviceType and serviceType tags and I need to extract them all, not just the first occurrence. Thanks.
Posted 2-Dec-12 21:48pm
Updated 3-Dec-12 0:45am
v4
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

You have to handle the namespace in your code, e.g.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
      nsmgr.AddNamespace("x", "urn:schemas-upnp-org:device-1-0");
      string deviceType = doc.DocumentElement.SelectSingleNode("./x:device/x:deviceType", nsmgr).InnerText;


Please note the XML document you posted in invalid: there is a spurious deviceType closing tag near the end:

</serviceList>
</deviceType> <==== ERROR HERE
</device>
</root>
  Permalink  
Comments
Trapper-Hell 3-Dec-12 6:50am
   
Great observation! I wrote the end tags myself since the true XML was too long, and I just extracted the important aspects of it. Please ignore the erroneous tag in the end (I revised it in the original post).

With regards to your proposed solution, it worked :D So I'm quite glad! Before I accept the solution, can you kindly explain why you had to add the namespace (and its importance)?

And finally, there are other <deviceType> tags that are children of other tags (under some branch under the <service> tag). Is it possible that I search for all <deviceType> tags irrelevant of their position within the document?
CPallini 3-Dec-12 7:58am
   
You have to add the namespace because the namespace attribute is inherited by all the children of the root node.

To select all the deviceType tags the way you depicted use the '//' in the XPath query, see
http://www.tizag.com/xmlTutorial/xpathdescendant.php
Trapper-Hell 3-Dec-12 8:09am
   
That about sums it all up :) Thank you for your time!
CPallini 3-Dec-12 8:28am
   
You are welcome.
Trapper-Hell 3-Dec-12 8:15am
   
Sorry to be bothering you again, but I tried the following code:

int deviceCounter = doc.DocumentElement.SelectNodes("./x:device//x:deviceType").Count;

However that gives an XPathException. What am I doing wrong here?
CPallini 3-Dec-12 8:30am
   
I don't know: your code gives me 1, on your original XML file.
Trapper-Hell 3-Dec-12 8:38am
   
XmlDocument doc = new XmlDocument();
doc.Load("C:\\\\xml.xml");

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("x", "urn:schemas-upnp-org:device-1-0");
string deviceType = doc.DocumentElement.SelectSingleNode("./x:device/x:deviceType", nsmgr).InnerText;
int deviceCounter = doc.DocumentElement.SelectNodes("./x:device//x:deviceType").Count;

That's the code I'm using the XML I submitted. It throws an XPath Exception with the following message: "Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function."
CPallini 3-Dec-12 9:15am
   
You must use the namespace manager nsmgr (like you did before), namely:
int deviceCounter = doc.DocumentElement.SelectNodes("./x:device//x:deviceType", nsmgr).Count;
Trapper-Hell 3-Dec-12 9:18am
   
That totally passed me - I can't get used to it yet. *Feels dumb* Sorry and thanks for all the support :)
CPallini 3-Dec-12 9:24am
   
You are welcome again. I felt the same the very first time I had the namespace issue.
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

Simple example is given over here[^]...
  Permalink  
Comments
Trapper-Hell 3-Dec-12 4:04am
   
I'd have preferred a more tailored solution rather than a link, however I have considered the submitted link and tried the following line of code:

XmlNode node = doc.SelectSingleNode("deviceType");

However the node variable is null.
Krunal Rohit 3-Dec-12 4:07am
   
How it could be possible ?? Try to put breakpoint over there and debug it..
Trapper-Hell 3-Dec-12 4:44am
   
I did place a breakpoint to go through the process but I'm not sure what I'm supposed to notice.

The code thus far is fairly simple:

------------

XmlDocument doc = new XmlDocument();
doc.Load("C:\\\\IGD.xml");

XmlNode node = doc.SelectSingleNode("deviceType");

------------

After going over the third line, the node variable remains null. I've tested that the doc is loaded fine and it would seem so, but it cannot select the tag. Could it be because the first line of the XML is non-standard XML ?
Krunal Rohit 3-Dec-12 4:45am
   
Are you getting error on first line or else ??
Trapper-Hell 3-Dec-12 4:47am
   
I am not getting any errors on the lines posted. It all seems to work fine, however the node variable remains null. So if I were to add a line like this afterwards:

string extension = node.ChildNodes[0].InnerText;

I'd get a NullReferenceExecption since the node variable remains null.
Trapper-Hell 3-Dec-12 4:56am
   
Can you possibly try the provided sample XML yourself to see if you can extract the text?

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

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Mobile
Web02 | 2.8.170713.1 | Last Updated 3 Dec 2012
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100