microkarl Posted August 5, 2004 Posted August 5, 2004 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 Quote Donald DUCK : YOU ARE FIRED!!!
*Experts* Nerseus Posted August 5, 2004 *Experts* Posted August 5, 2004 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 Quote "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
microkarl Posted August 5, 2004 Author Posted August 5, 2004 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.. Quote Donald DUCK : YOU ARE FIRED!!!
*Experts* Nerseus Posted August 6, 2004 *Experts* Posted August 6, 2004 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 Quote "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
microkarl Posted August 6, 2004 Author Posted August 6, 2004 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 Quote Donald DUCK : YOU ARE FIRED!!!
*Experts* Nerseus Posted August 6, 2004 *Experts* Posted August 6, 2004 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 Quote "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
microkarl Posted August 6, 2004 Author Posted August 6, 2004 Yup... Got it (finally....>_<) Thanks a ton Quote Donald DUCK : YOU ARE FIRED!!!
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.