Click here to Skip to main content
15,890,897 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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:

XML
<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
Updated 3-Dec-12 0:45am
v4

You have to handle the namespace in your code, e.g.
C#
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>
 
Share this answer
 
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?
Simple example is given over here[^]...
 
Share this answer
 
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.
[no name] 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 ?
[no name] 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.

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