Groups | Blog | Home
all groups > dotnet xml > june 2007 >

dotnet xml : Newbie Xpath Question


Edgardo
6/24/2007 8:00:00 PM
Hi everyone, i have a quesiton regarding XML/Xpath

i have a XML document that has let say the following structure

<cases>
<case>
<num>1<num>
<detective>
<name>John</name>
<lastname>Smith</lastname>
<detective>
</case>
<case>
<num>2<num>
<detective>
<name>Roger</name>
<lastname>Wilco</lastname>
<detective>
</case>
</cases>


I want to know, what would be the most "by the book" way to get all the
values from the cases nodes into variables for further work.
I need to "spider" XML files that have a defined structure, they wont change
their structure from one day to another, but i need do get the cleanes way to
get these values into variables som each loop of the
nodelist/nodeiterator/cursor i do some calculations.

I see a lot of examples telling me jus thow to print out the whole content
of a element, but not how to acces a child element or subnode and get its
value.

something that would help me do like

while node.read()
case = node.current
mymun = case.num
mydetname = case.det.name
mydetlastname = case.det.lastname
wend

Oviously i know it wont be that way, im just writng the way i would need to
get the variables.

I hope you can help me, any idea, suggestion, url that you can give me would
be really appreciated.

Thanks

Rick
6/25/2007 12:00:00 AM
I haven't done any of this in a while, but this should point you in the
right direction...

If you want to get all the "detective" nodes from the xml document:

nodes = xmlDoc.SelectNodes("cases/")

Completely untested, but that should give you all the "case" nodes so you
can process them further.

Rick


[quoted text, click to view]

Edgardo
6/25/2007 7:30:01 AM
Thank you all for the help! ;)

I'll try those tonight and let you know what happens.

Regards

-Ed
Edgardo
6/25/2007 10:01:04 AM
Thanks for the tip WenYuan, im working with VB and framework 1.1 and im not
getting this line to work

string mydelastname = xn["detective"]["lastname"].InnerText;

i tryed xnl("detective")("lastname").innertText

but doesn not work

any ideas?

Best Regards



[quoted text, click to view]
Edgardo
6/25/2007 10:42:00 AM
Thanks for the help Martin, i get

Object reference not set to an instance of an object.

i and double checked the spelling and its correct

any suggestions?

-Ed

[quoted text, click to view]
v-wywang NO[at]SPAM online.microsoft.com
6/25/2007 12:12:24 PM
Hello ED,
Thanks for Rick's suggestion.

I also agree with him. The best way is to retrieve all Case nodes and get
the values from its nested node.

System.Xml.XmlDocument xd = new System.Xml.XmlDocument();
xd.Load("XX.xml");
System.Xml.XmlNodeList xnl = xd.SelectNodes(@"/cases/case");
foreach (System.Xml.XmlNode xn in xnl)
{
string mynum= xn["num"].InnerText;
string mydetname = xn["detective"]["name"].InnerText;
string mydelastname = xn["detective"]["lastname"].InnerText;
}

Hope this helps. If you meet any further issue, feel free to update here.
I'm glad to assist you.

Have a great day,
Sincerely,
Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Martin Honnen
6/25/2007 2:02:34 PM
[quoted text, click to view]

If you don't want to change the XML and want to use XPath to access
nodes then use XPathDocument/XPathNavigator, for instance as follows in
..NET 2.0 or later:

XPathDocument doc = new XPathDocument(@"file.xml");
XPathNavigator navigator = doc.CreateNavigator();
XPathNodeIterator iterator = navigator.Select(@"cases/case");
while (iterator.MoveNext())
{
int num =
iterator.Current.SelectSingleNode("num").ValueAsInt;
string name =
iterator.Current.SelectSingleNode("detective/name").Value;
string lastname =
iterator.Current.SelectSingleNode("detective/lastname").Value;
Console.WriteLine("Number {0} has name {1} {2}.", num,
name, lastname);
}

You could also consider XML deserialization, that way you do not have to
know XPath.

--

Martin Honnen --- MVP XML
Martin Honnen
6/25/2007 7:16:52 PM
[quoted text, click to view]

That should be
xnl("detective")("lastname").InnerText

If you still have problems then tell us exactly which error message you get.

--

Martin Honnen --- MVP XML
Edgardo
6/25/2007 7:46:01 PM
I think i saw something that might be causing the error..

Guys, will it affect if the structure is like the following?

<cases>
<case>
<num>1<num>
<detective>
<name>John1</name>
<lastname>Smith1</lastname>
<detective>
<detective>
<name>John2</name>
<lastname>Smith2</lastname>
<detective>
</case>
<case>
<num>2<num>
<detective>
<name>Roger1</name>
<lastname>Wilco1</lastname>
<detective>
<detective>
<name>Roger2</name>
<lastname>Wilco2</lastname>
<detective>
</case>
</cases>
Edgardo
6/25/2007 8:01:03 PM
Ok, dont ask me how, now its working but the problem is how can i get the
values of the secons instance of "detective"??

xnl("detective")("lastname").InnerText = "Smith1"
????? = "Smith2"

Best Regards

v-wywang NO[at]SPAM online.microsoft.com
6/26/2007 12:00:00 AM
Hello Edgardo
Thanks for Martin's help.

I think you have found the key point.
The structure of XML could affect the result.

Please notice there are two DETECTIVE node nested in same Case node
<case>
<num>1</num>
* <detective>
<name>John1</name>
<lastname>Smith1</lastname>
</detective>
*<detective>
<name>John2</name>
<lastname>Smith2</lastname>
</detective>
</case>

xnl("detective") could only get the FIRST node named DETECTIVE. Thus, if
the number of DETECTIVE node is greater than ONE, we would have to retrieve
each node by xnl.selectNodes("detective") mothed rather than
xnl("detective").

Please check the following code snippet.

Dim xd As System.Xml.XmlDocument = New System.Xml.XmlDocument
xd.Load("XMLFile1.xml")
Dim xnlCa As System.Xml.XmlNodeList = xd.SelectNodes("/cases/case")
For Each xnCa As System.Xml.XmlNode In xnlCa
Dim mynum As String = xnCa("num").InnerText

Dim xnlDet As System.Xml.XmlNodeList = xnCa.SelectNodes("detective")
For Each xnDet As System.Xml.XmlNode In xnlDet
Dim mydetName As String = xnDet("name").InnerText
Dim mydetLastName As String = xnDet("lastname").InnerText
Next

Next

BTW, you could aslo retrieve each node by array. For eaxample:

Dim xd As System.Xml.XmlDocument = New System.Xml.XmlDocument
xd.Load("XMLFile1.xml")
Dim xnlCa As System.Xml.XmlNodeList = xd.SelectNodes("/cases/case")
For Each xnCa As System.Xml.XmlNode In xnlCa
Dim mynum As String = xnCa("num").InnerText

Dim xnlDet As System.Xml.XmlNodeList = xnCa.SelectNodes("detective")
Dim mydetName1 As String = xnlDet(0)("name").InnerText ' = "John1"
Dim mydetLastName1 As String = xnlDet(0)("lastname").InnerText ' =
"Smith1"
Dim mydetName2 As String = xnlDet(1)("name").InnerText ' = "John2"
Dim mydetLastName2 As String = xnlDet(1)("lastname").InnerText ' =
"Smith2"

Next

Hope this helps.Please let us know if you meet any further issue. We are
glad to assist you.
Have a great day,
Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Edgardo
6/26/2007 10:31:08 AM
Thanks a lot WenYuan, i really appreciate your help, i've read a lot on the
web, but on ly simple examples come up, this is really helpful, i'll give it
a try tonigh.

-Ed

[quoted text, click to view]
v-wywang NO[at]SPAM online.microsoft.com
6/27/2007 2:54:14 AM

The pleasure is mine.:)
Welcome, Ed.
I will wait for you. Please let me know if you meet any further issue.

Have a great day,
Sincerely,
Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.


v-wywang NO[at]SPAM online.microsoft.com
6/29/2007 12:08:00 PM
Hello Ed

This is Wen Yuan. Have you tried the method so far?
If you meet any further issue on this, feel free to update here again.
We are glad to assist.:)

Have a great weekend.
Sincerely,
Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
AddThis Social Bookmark Button