Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

All,

I have a problem using XPath. Just wondering if I can get some help. Let's look at the following XML.

 

<Books>

<History Book="1">

<Italian Category="1" Cost="70" />

<Italian Category="1" Cost="70" />

<English Category="1" Cost="20" />

<English Category="1" Cost="20" />

<English Category="1" Cost="50" />

<English Category="3" Cost="20" />

<English Category="1" Cost="10" />

<English Category="2" Cost="50" />

<German Category="1" Cost="70" />

</History>

</Books>

 

I have this (sample) XML and I want to retrieve ONLY all the English with Category = "1" and Cost = "20"

 

Is there an easy way to do (it doesn't nessessary be XPath).. please let me know ASAP

 

Carl

Donald DUCK : YOU ARE FIRED!!!
  • *Experts*
Posted

Try:

/Books/History/English[Category=1' and Cost='20]

 

That will return the English nodes that match the criteria.

Feel free to use * for nodes you don't care about, such as:

/*/*/English[Category=1' and Cost='20]

 

Or if "English" nodes only appear at the one level, you can shorten it to:

//English[Category=1' and Cost='20]

 

I would guess the first sample is fastest (maybe/maybe not) because of the fully qualified path.

 

-ner

"I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Posted

Here's my code

 

Dim expr As string = "/Books/History/English[Category=1' and Cost='20]"

 

Dim devices As XmlNode = document.SelectNodes(expr).Item(0)

If devices.ChildNodes.Count > 0 Then

For deviceIndex = 0 To devices.ChildNodes.Count - 1

lstOut.Items.Add(devices.ChildNodes.Item(deviceIndex).OuterXml)

lstOut.Items.Add(expr)

Next

Else

lstOut.Items.Add("0 Nodes matched")

lstOut.Items.Add(expr)

End If

 

And it fails..

Donald DUCK : YOU ARE FIRED!!!
  • *Experts*
Posted

You're taking the first match and looping through it's child nodes/elements, but English has no child elements.

 

I'm not sure what text you're trying to get at, but to find English nodes and loop through them, try this:

Dim expr As string = "/Books/History/English[Category='1' and Cost='20']"
Dim matches As XmlNode
For Each match In document.SelectNodes(expr)
   lstOut.Items.Add(match.InnerXml)
Next

 

From your snippet, there is nothing I see that you'd select to put into a listbox. If you show me the full sample xml I might be able to help more.

 

Keep in mind that SelectNodes returns a nodelist of matches. You were grabbing the first match (an English node, if one matched) and looping through it's child nodes. For that to work, your xml would have to look like:

<Books>
   <History>
       <English>
           <InnerNode/>
       </English>
   </History>
</Books>

 

In that case, InnerNode would be a childnode.

-nerseus

"I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Posted

Nerseus, Thanks for your reply.

Okay, What I really want to do is add up the amount of books that match these two critieria: English & Category = 1.

 

And I modified your code to this:

 

Dim document As XmlDocument = New XmlDocument

document.Load("C:\Documents and Settings\tam\Desktop\Books.xml")

 

Dim strExpr As String = "/Books/History/English"

 

by the way, I used this

Dim strExpr As String = "/Books/History/English[Category=1' and Cost='20]"

but, it keeps return nothing.

 

 

Dim match As XmlNode

If document.SelectNodes(strExpr).Count = 0 Then

lstOut.Items.Add("0 Nodes matched")

Else

For Each match In document.SelectNodes(strExpr)

lstOut.Items.Add(match.OuterXml)

Next

End If

 

and it reutrns somthing like this:

<English Category="1" Cost="20" />

<English Category="1" Cost="20" />

<English Category="1" Cost="50" />

<English Category="3" Cost="20" />

<English Category="1" Cost="10" />

<English Category="2" Cost="50" />

 

I thought at this point, I can take one more step to filter up Category="1"

But, when I look at the "match" object, it doesn't have attributes for me to grab... so, how am I gonna extract the books that I really want??

 

Please help

 

Thanks

Donald DUCK : YOU ARE FIRED!!!
  • *Experts*
Posted

Whoops - my bad. To filter on attributes you must prefix them with @. Try this instead:

Dim strExpr As String = "/Books/History/English[@Category=1' and @Cost='20]"

 

-ner

"I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...