Parsing XML into List view
Hey,
I have written a function which logs into an FTP server and recursively lists all of the directories within a given folder into an XML string (example below).
I basically want to parse this into a listview item in the format as follows "Level1/level2/level3/level4" (standard file path). I have given an example of the xml below. How would I go about achieving this?
I have set up an xmltextreader, and then using a do while xmltextreader.read() I can check the current level of the node and add it that way, but it tends to only work half the time - is this the best approach?
Code:
<dirTree>
<dir name="Highest level" />
<dir name="Highest Level 2">
<dir name="level 2" />
<dir name="level 2a" />
<dir name="level 2b">
<dir name="level 3" />
</dir>
<dir name="level 2c" />
</dir>
<dir name="Highest Level 3" />
<dir name="Highest Level 4" />
</dirTree>
Code:
Highest Level
Highest Level 2
Highest Level 2/level 2
Highest Level 2/level 2a
Highest Level 2/level 2b
Highest Level 2/level 2b/level3
Highest Level 2/level 2c
Highest Level 3
Highest Level 4
Regards,
Adam.
Re: Parsing XML into List view
try this:
vb Code:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim xml = _
<dirTree>
<dir name="Highest level"/>
<dir name="Highest Level 2">
<dir name="level 2"/>
<dir name="level 2a"/>
<dir name="level 2b">
<dir name="level 3"/>
</dir>
<dir name="level 2c"/>
</dir>
<dir name="Highest Level 3"/>
<dir name="Highest Level 4"/>
</dirTree>
'read up to 3 levels from xml + display in listview
Dim items = From node In xml...<dir> _
Select New String() {node.@name, node...<dir>.@name, node...<dir>...<dir>.@name}
For Each i In items
Dim subItems() As String = (From s In i Where s <> Nothing Select s).ToArray
ListView1.Items.Add(New ListViewItem(subItems))
Next
End Sub
End Class
Re: Parsing XML into List view
Paul, I don't think you can assume there is only a maximum depth of 3 levels. Since it is a file structure from an FTP server I'm sure the nesting can be 'infinitely' deep, so you will probably need some kind of recursion. I'm not sure if LINQ supports recursion (I think it does in some complicated way) so maybe LINQ is not the best option in this case.
Re: Parsing XML into List view
Hiya,
Basically that's the same problem that I currently have, that I can only get it to read x levels into the FTP file, not recursively. Now, I'm aware there is a maximum number, something like 30,000 folders, but I really wouldn't like to go to that much trouble.
I've never used LINQ before, but will take a look at it
Re: Parsing XML into List view
I would just create some recursive function that
1) Creates a string with the name of the current node,
2) Then for each child 'dir' node, append the result of this same function (recursively) to that string
3) Return the string.
Something like that should work. You could still use the XDocument class to get the child nodes very easily, something like
Code:
For Each childDir In dir...<dir>
where 'dir' is an XElement containing the parent 'dir' node.
Then you could use the @ symbol to quickly get the name attribute:
But I wouldn't use LINQ in this case. It is very useful, but I don't think recursion is very easy to do, if possible at all. Likely it is possible, but it would probably be quite difficult to even read and understand it, and in such cases I think that using LINQ is not the right idea. It is supposed to make things easier to read by avoiding things like nested loops, so making a very hard to read LINQ query versus creating a simple recursive function is a little backwards...
Re: Parsing XML into List view
here is an example although it uses tree view:
http://support.microsoft.com/kb/308063
I used it before and works fine.
Re: Parsing XML into List view
Hey,
I've taken that code and slightly adapted it to the following:
VB.NET Code:
Private Sub PopulateTree(ByVal xml As String)
Try
' SECTION 1. Create a DOM Document and load the XML data into it.
Dim dom As New XmlDocument
dom.LoadXml(xml)
' SECTION 2. Initialize the treeview control.
TreeView1.Nodes.Clear()
TreeView1.Nodes.Add(New TreeNode(dom.DocumentElement.Name))
Dim tNode As New TreeNode()
tNode = TreeView1.Nodes(0)
' SECTION 3. Populate the TreeView with the DOM nodes.
AddNode(dom.DocumentElement, tNode)
TreeView1.ExpandAll()
Catch xmlEx As XmlException
MessageBox.Show(xmlEx.Message)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub AddNode(ByRef inXmlNode As XmlNode, ByRef inTreeNode As TreeNode)
Dim xNode As XmlNode
Dim tNode As TreeNode
Dim nodeList As XmlNodeList
Dim i As Integer
' Loop through the XML nodes until the leaf is reached.
' Add the nodes to the TreeView during the looping process.
If inXmlNode.HasChildNodes() Then
nodeList = inXmlNode.ChildNodes
For i = 0 To nodeList.Count - 1
xNode = inXmlNode.ChildNodes(i)
inTreeNode.Nodes.Add(New TreeNode(xNode.Name))
tNode = inTreeNode.Nodes(i)
AddNode(xNode, tNode)
Next
Else
' Here you need to pull the data from the XmlNode based on the
' type of node, whether attribute values are required, and so forth.
inTreeNode.Text = (inXmlNode.OuterXml).Trim
End If
End Sub
Just so that I can call it from a different procedure, and input the XML as a string rather than a file name. I also think that my problem lies with the "AddNode(dom.DocumentElement, tNode)" line. But all the tree nodes appear as "<dir foldername />" rather than "foldername"
Is there anyway to change this?
Regards
Re: Parsing XML into List view
I did not check it, but change this line:
inTreeNode.Text = (inXmlNode.OuterXml).Trim
to whatever the property. I guess the outerxml = <dir .../>, so, just denug it, and change it.
it could be innertext, or something similar.
Re: Parsing XML into List view
nice recursion:
vb Code:
Private Sub AddNode(ByRef inXmlNode As XmlNode, ByRef inTreeNode As TreeNode)
Dim xNode As XmlNode
Dim tNode As TreeNode
Dim nodeList As XmlNodeList
Dim i As Integer
' Loop through the XML nodes until the leaf is reached.
' Add the nodes to the TreeView during the looping process.
If inXmlNode.HasChildNodes() Then
nodeList = inXmlNode.ChildNodes
For i = 0 To nodeList.Count - 1
xNode = inXmlNode.ChildNodes(i)
inTreeNode.Nodes.Add(New TreeNode(xNode.Attributes("name").Value))
tNode = inTreeNode.Nodes(i)
AddNode(xNode, tNode)
Next
Else
' Here you need to pull the data from the XmlNode based on the
' type of node, whether attribute values are required, and so forth.
inTreeNode.Text = inXmlNode.Attributes("name").Value
End If
End Sub