472,146 Members | 1,286 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,146 software developers and data experts.

All available xpath in XML document

9
I am using vb.net 2010 to get data from XML file, I was wondering if there is any way to find and print all available xpath of all nodes in the document. For example:
XML file is like :
Expand|Select|Wrap|Line Numbers
  1. <CATALOG>
  2.   <CD>
  3.     <TITLE>Empire Burlesque</TITLE>
  4.     <ARTIST>Bob Dylan</ARTIST>
  5.   </CD>
  6.   <CD>
  7.     <TITLE>Hide your heart</TITLE>
  8.     <ARTIST>Bonnie Tyler</ARTIST>
  9.   </CD>
The result should be something like :

/CATALOG
/CATALOG/CD
/CATALOG/CD/TITLE
/CATALOG/CD/ARTIST

I hope I'm clear enough..
May 26 '10 #1

✓ answered by oscar2

It is rather confusing right :)
Now at last I got it to work. Check this out:

Expand|Select|Wrap|Line Numbers
  1. Sub GetPaths(ByVal node As Xml.XmlNode, ByVal paths As List(Of String), Optional ByVal path As String = "")
  2.         path &= "/" & node.Name
  3.         If Not paths.Contains(path) Then
  4.             paths.Add(path)
  5.             lstPaths.Items.Add(path)
  6.         End If
  7.         For Each child As Xml.XmlNode In node.ChildNodes
  8.             If child.NodeType = Xml.XmlNodeType.Element Then
  9.                 GetPaths(child, paths, path)
  10.             End If
  11.         Next
  12.     End Sub
and...

Expand|Select|Wrap|Line Numbers
  1. Dim xDoc As New XmlDocument
  2. Dim paths As New List(Of String)
  3. GetPaths(xDoc.DocumentElement, paths)
  4. lstPaths.SelectedIndex = 0

Problem solved ;)

9 3076
Dormilich
8,658 Expert Mod 8TB
I was wondering if there is any way to find and print all available xpath of all nodes in the document.
there’s more than just those 4 XPaths. you can have relative XPaths, you can have XPaths with conditions, with selectors, etc. etc.

what you possibly mean is a document tree representation.
May 26 '10 #2
oscar2
9
In fact I need those 4 paths and of course if there is another node inside say TITLE I need a path to that node as well. All paths should start from the Root node CATALOG in this case. It might be worth mentioning that I will then feed those paths to a list to give the user an easy way to select the node or node-set to be modified.
Thanks :)
May 26 '10 #3
jkmyoung
2,057 Expert 2GB
I've done this with xslt before; it's possible to do it with other languages as well. It's recursion; Pseudocode:
Expand|Select|Wrap|Line Numbers
  1. Start at document level. 
  2. call f(rootnode, "")
  3.  
  4.  
  5. f(Node n, String s){
  6.   For each child node of n {
  7.     path = s + \ + node name
  8.     print path
  9.     child.f(n, path)
  10.   }
  11. }
May 27 '10 #4
oscar2
9
Thanks I am working on something similar.. will post here if I get the same result with VB.net
Thanks again
May 27 '10 #5
oscar2
9
I am working with this right now, This recursive sub can easily find path of all children but it will miss any sibling!

Expand|Select|Wrap|Line Numbers
  1. Public Class Form1
  2.     Public path As String
  3.  
  4.     Private Sub cmdRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRun.Click
  5.         Dim xDoc As XmlDocument = New XmlDocument
  6.         xDoc.Load("C:\Temp\file.xml")
  7.         Dim node As XmlNode = xDoc.SelectSingleNode("/catalog")
  8.         path = node.Name
  9.         GetPath(node)
  10.     End Sub
  11.  
  12.     Private Sub GetPath(ByVal node As XmlNode)
  13.         lst.Items.Add(path)
  14.  
  15.         If node.HasChildNodes = True Then  ' <==> If Not node.NodeType = XmlNodeType.Text Then 
  16.             path = path & "/" & node.FirstChild.Name
  17.             node = node.FirstChild
  18.             GetPath(node)
  19.         End If
  20.     End Sub
  21.  
  22. End Class
  23.  
Hope someone can build on this and give some insights.
May 27 '10 #6
jkmyoung
2,057 Expert 2GB
Lines 15 - 19.
You're only attacking the first child. You should be able to put just
if node.HasChildNodes
(remove the = true)

I'm not sure of the exact syntax in vb, but it goes something like:
Expand|Select|Wrap|Line Numbers
  1. dim children = node.ChildNodes
  2. For i = 0 To children.length
  3.   dim child = children[i]
  4.   path = path & "/" & child.Name 
  5.   GetPath(child) 
  6. Next i
  7.  
May 28 '10 #7
oscar2
9
Thanks.. i working on it :)
May 28 '10 #8
jkmyoung
2,057 Expert 2GB
Note, edited the above code, accidentally put GetPath(node) when I meant
GetPath(child)
May 28 '10 #9
oscar2
9
It is rather confusing right :)
Now at last I got it to work. Check this out:

Expand|Select|Wrap|Line Numbers
  1. Sub GetPaths(ByVal node As Xml.XmlNode, ByVal paths As List(Of String), Optional ByVal path As String = "")
  2.         path &= "/" & node.Name
  3.         If Not paths.Contains(path) Then
  4.             paths.Add(path)
  5.             lstPaths.Items.Add(path)
  6.         End If
  7.         For Each child As Xml.XmlNode In node.ChildNodes
  8.             If child.NodeType = Xml.XmlNodeType.Element Then
  9.                 GetPaths(child, paths, path)
  10.             End If
  11.         Next
  12.     End Sub
and...

Expand|Select|Wrap|Line Numbers
  1. Dim xDoc As New XmlDocument
  2. Dim paths As New List(Of String)
  3. GetPaths(xDoc.DocumentElement, paths)
  4. lstPaths.SelectedIndex = 0

Problem solved ;)
May 28 '10 #10

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

1 post views Thread by bdinmstig | last post: by
4 posts views Thread by Neil Cherry | last post: by
reply views Thread by Ramesh | last post: by
2 posts views Thread by Praveen | last post: by
6 posts views Thread by Derek Hart | last post: by
reply views Thread by Saiars | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.