By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,998 Members | 2,837 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,998 IT Pros & Developers. It's quick & easy.

How to add parent node in Vb.NET

P: n/a
Hi,

I am having an XML document(input.xml) which is showing the menu heirarchy
used in my application.My requirement is to add "submenu" tag to those
menuitems who are having the child menuitems as shown in output.xml.
I am using VB.NET framework 1.1.

Please Help, i have already invested my 2 days but unable to build the logic
as input xml may be having any level of nesting of menuitems.

input.xml
***************************************
<menu>
<menuItem>
<text>HOME</text>
<javascriptcommand>opennewwindow('home.aspx')</javascriptcommand>
<cssclass>off</cssclass>
<MENU_ID>1</MENU_ID>
</menuItem>
<menuItem>
<text>QUERY</text>
<javascriptcommand>openPopup('fundSearch.aspx','Se arch', 580,
200)</javascriptcommand>
<cssclass>off</cssclass>
<MENU_ID>2</MENU_ID>
</menuItem>
<menuItem>
<text>REPORTS</text>
<cssclass>off</cssclass>
<MENU_ID>3</MENU_ID>
<menuItem>
<text>Standard Reports</text>
<MENU_ID>5</MENU_ID>
<PRNT_MENU_ID>3</PRNT_MENU_ID>
<menuItem>
<text>PM Tenure</text>
<MENU_ID>7</MENU_ID>
<PRNT_MENU_ID>5</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Performance</text>
<MENU_ID>8</MENU_ID>
<PRNT_MENU_ID>5</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Fee & Expenses</text>
<MENU_ID>9</MENU_ID>
<PRNT_MENU_ID>5</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Fact Sheet PDFs</text>
<MENU_ID>10</MENU_ID>
<PRNT_MENU_ID>5</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Fund Facts</text>
<MENU_ID>11</MENU_ID>
<PRNT_MENU_ID>5</PRNT_MENU_ID>
</menuItem>
</menuItem>
<menuItem>
<text>Custom Reports</text>
<MENU_ID>6</MENU_ID>
<PRNT_MENU_ID>3</PRNT_MENU_ID>
<menuItem>
<text>Spectrums</text>
<MENU_ID>12</MENU_ID>
<PRNT_MENU_ID>6</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Performance</text>
<MENU_ID>13</MENU_ID>
<PRNT_MENU_ID>6</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Descriptions</text>
<MENU_ID>14</MENU_ID>
<PRNT_MENU_ID>6</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Fund Actions</text>
<MENU_ID>15</MENU_ID>
<PRNT_MENU_ID>6</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Inv Svcs Only</text>
<MENU_ID>16</MENU_ID>
<PRNT_MENU_ID>6</PRNT_MENU_ID>
</menuItem>
</menuItem>
</menuItem>
<menuItem>
<text>HELP</text>
<cssclass>off</cssclass>
<MENU_ID>4</MENU_ID>
<menuItem>
<text>FAQs</text>
<MENU_ID>17</MENU_ID>
<PRNT_MENU_ID>4</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>How To</text>
<MENU_ID>18</MENU_ID>
<PRNT_MENU_ID>4</PRNT_MENU_ID>
</menuItem>
</menuItem>
</menu>

output.xml
************************************************** ***
<menu>
<menuItem>
<text>HOME</text>
<javascriptcommand>opennewwindow('home.aspx')</javascriptcommand>
<cssclass>off</cssclass>
<MENU_ID>1</MENU_ID>
</menuItem>
<menuItem>
<text>QUERY</text>
<javascriptcommand>openPopup('fundSearch.aspx','Se arch', 580,
200)</javascriptcommand>
<cssclass>off</cssclass>
<MENU_ID>2</MENU_ID>
</menuItem>
<menuItem>
<text>REPORTS</text>
<cssclass>off</cssclass>
<MENU_ID>3</MENU_ID>
<submenu>
<menuItem>
<text>Standard Reports</text>
<MENU_ID>5</MENU_ID>
<PRNT_MENU_ID>3</PRNT_MENU_ID>
<submenu>
<menuItem>
<text>PM Tenure</text>
<MENU_ID>7</MENU_ID>
<PRNT_MENU_ID>5</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Performance</text>
<MENU_ID>8</MENU_ID>
<PRNT_MENU_ID>5</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Fee & Expenses</text>
<MENU_ID>9</MENU_ID>
<PRNT_MENU_ID>5</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Fact Sheet PDFs</text>
<MENU_ID>10</MENU_ID>
<PRNT_MENU_ID>5</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Fund Facts</text>
<MENU_ID>11</MENU_ID>
<PRNT_MENU_ID>5</PRNT_MENU_ID>
</menuItem>
</submenu>
</menuItem>
<menuItem>
<text>Custom Reports</text>
<MENU_ID>6</MENU_ID>
<PRNT_MENU_ID>3</PRNT_MENU_ID>
<submenu>
<menuItem>
<text>Spectrums</text>
<MENU_ID>12</MENU_ID>
<PRNT_MENU_ID>6</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Performance</text>
<MENU_ID>13</MENU_ID>
<PRNT_MENU_ID>6</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Descriptions</text>
<MENU_ID>14</MENU_ID>
<PRNT_MENU_ID>6</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Fund Actions</text>
<MENU_ID>15</MENU_ID>
<PRNT_MENU_ID>6</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>Inv Svcs Only</text>
<MENU_ID>16</MENU_ID>
<PRNT_MENU_ID>6</PRNT_MENU_ID>
</menuItem>
</submenu>
</menuItem>
</submenu>
</menuItem>
<menuItem>
<text>HELP</text>
<cssclass>off</cssclass>
<MENU_ID>4</MENU_ID>
<submenu>
<menuItem>
<text>FAQs</text>
<MENU_ID>17</MENU_ID>
<PRNT_MENU_ID>4</PRNT_MENU_ID>
</menuItem>
<menuItem>
<text>How To</text>
<MENU_ID>18</MENU_ID>
<PRNT_MENU_ID>4</PRNT_MENU_ID>
</menuItem>
</submenu>
</menuItem>
</menu>

Thanks & Regards,
Neeraj
Mar 22 '06 #1
Share this Question
Share on Google+
14 Replies


P: n/a
Hi,

I'm not sure I understand you correctly, but I think you need to insert
a <subMenu> element before each nested <menuItem> element. In other
words, you want to convert input.xml so that it looks like output.xml
???

Is that so ? If so, could you post whatever logic you have come up with
till now ?

Regards,

Cerebrus.

Mar 22 '06 #2

P: n/a
I'm having trouble getting an Xpath Expression to pick out the relevant
nodes

e.g.
descendant::menuItem[parent::menuItem][not(preceding-sibling::menuItem)]

Cerebus - I Would like to see to insert a new parent node around the
relevant menuItem node after having got the relevant nodes in a
nodelist

i.e.

xdoc.Load("xpath.xml")

Dim nl As XmlNodeList = xdoc.DocumentElement. _
SelectNodes("descendant::menuItem[parent::menuItem][not(preceding-sibling::menuItem)]")

For Each xnode In nl

txEle = xdoc.CreateElement("submenu")
txEle.AppendChild(xnode)

'Now how do we update xdoc
'replacing xnode with txEle
' because at this point in code we dont know where we
are in xdoc
Next
Dickster

Mar 23 '06 #3

P: n/a
Hi Dickster,

Is your question an answer to Neeraj's question ? Or is your question
separate from Neeraj's original question ?

The way I was thinking of solving Neeraj's problem was : (xDoc is the
XmlDocument)

1. Get a NodeList containing all Top level "menuItem" nodes, using
xDoc.SelectNodes("/menu/menuItem")
2. Iterate through this list, calling a method, say "ParseChildren()"
3. The ParseChildren method will recursively process each child
"menuItem" node, using SelectSingleNode(".//menuItem")
4. During processing, it creates an XmlDocumentFragment containing all
the OuterXml of the "menuItem" node.
5. It then creates a "subMenu" element just before this "menuItem"
node. Then the XmlDocumentFragment is appended as a child to this
"subMenu" element.
6. The original "menuItem" node is then deleted.
7. The loop moves on to the next sibling "menuItem" node, if no sibling
exists, it moves to the parent's next sibling.

I've got some of the code to work (uptill step 6), but I'm still stuck
at iterating through the siblings. Hopefully I'll find some time to
debug my code soon.

The XPath expression you presented selects only the first nested
"menuItem" element, since you have added the
not(preceding-sibling::menuItem) part.

HTH,

Regards,

Cerebrus.

Mar 23 '06 #4

P: n/a
Hi Cerebrus,
Thanks for the reply.
Your understandign perfectly correct.
The logic which we have to apply is we have to insert subMenu tag whenever
menuItem is having the child menuItem and all the child menuItem tags should
be enclosed in subMenu tag.
Like in my input xml menuItem "REPORTS" is having two child meuItems
Standard Reports and Custom Reports. so they should be come into "subMenu"
tag. Also Now Custom Reports is also having 5 menuItem childs, so they should
be enclosed in one SubMenu Tag.

It's very simple that Reports is top level Menu
Standard Reports and Custom Reports are second level menu
Child under Standard reports are third level menu

You can see in my output xml
Currently i am using the following logic but i am not sure will it work for
any level of nesting

please help in providing the bugproof logic.

For Each objMenuNode In objmenuItemNodeList
If (checkChildMenuItems(objMenuNode)) Then
Dim objSubMenuNode As System.Xml.XmlNode =
objDoc.CreateNode(System.Xml.XmlNodeType.Element, "subMenu", "")
menuitems = menuItemsArrayList(objMenuNode)
For counter = 0 To menuitems.Count - 1

objSubMenuNode.AppendChild(DirectCast(menuitems(co unter), XmlNode))
Next
objMenuNode.AppendChild(objSubMenuNode)
End If
Next

************************************************** *******************************************
Private Function checkChildMenuItems(ByVal sampleNode As XmlNode) As Integer
Dim returnvalue As Boolean
Dim i As Integer
returnvalue = False
For i = 0 To sampleNode.ChildNodes.Count - 1
If (sampleNode.ChildNodes(i).Name) = "menuItem" Then
returnvalue = True
Exit For
End If
Next
checkChildMenuItems = returnvalue
End Function

************************************************** *********************************************
Private Function menuItemsArrayList(ByVal sampleNode As XmlNode) As
ArrayList
Dim returnvalue As New ArrayList
Dim i As Integer
For i = 0 To sampleNode.ChildNodes.Count - 1
If (sampleNode.ChildNodes(i).Name) = "menuItem" Then
returnvalue.Add(sampleNode.ChildNodes(i))
End If
Next
menuItemsArrayList = returnvalue
End Function
"Cerebrus" wrote:
Hi,

I'm not sure I understand you correctly, but I think you need to insert
a <subMenu> element before each nested <menuItem> element. In other
words, you want to convert input.xml so that it looks like output.xml
???

Is that so ? If so, could you post whatever logic you have come up with
till now ?

Regards,

Cerebrus.

Mar 23 '06 #5

P: n/a
Hi dickster,

Thanks for the reply.

Your Xpath is not giving the required nodes. it should give menuItem nodes
which are having menuItem Childs so that we can enclose them in subMenu tags.

like in case of input xml it should give REPORTS,Standard Reports, Custom
Reports and HELP, so that we can include their menuitem tags in submenu tag.

"dickster" wrote:
I'm having trouble getting an Xpath Expression to pick out the relevant
nodes

e.g.
descendant::menuItem[parent::menuItem][not(preceding-sibling::menuItem)]

Cerebus - I Would like to see to insert a new parent node around the
relevant menuItem node after having got the relevant nodes in a
nodelist

i.e.

xdoc.Load("xpath.xml")

Dim nl As XmlNodeList = xdoc.DocumentElement. _
SelectNodes("descendant::menuItem[parent::menuItem][not(preceding-sibling::menuItem)]")

For Each xnode In nl

txEle = xdoc.CreateElement("submenu")
txEle.AppendChild(xnode)

'Now how do we update xdoc
'replacing xnode with txEle
' because at this point in code we dont know where we
are in xdoc
Next
Dickster

Mar 23 '06 #6

P: n/a
Hi Cerebus, - thanks for your reply.

Neerajb - thanks for your reply & sorry for hopping in on the back of
your query.

I'm referring to Neeraj problem as it is an example of problem I would
like to see solved.

i.e. how to

1. take a list of child nodes (XmlNodeList) which match a particular
Xpath expression but are dotted randomly throughout an XML hierarchy
2. Imbed each of those child nodes in a parent node (eg. <subItem>)
back into the main XML message

I had not thought of using the OuterXML property of XmlDocumentFragment

Cerebus -I am very interested to see how you do step 4/5/6.

Indeed my XPath was wrong - but I would be interested to see an XPath
Expression which would pick out the exact list of nodes Neeraj needs
imbedded in a new <subItem> node. - I'm not sure if this is
possible.

Dickster

Mar 23 '06 #7

P: n/a
My point really is this...

When iterating through each node in an XMlNodeList how do you know
where you are in the document hierarchy, in order to do this kind of
insert

Mar 23 '06 #8

P: n/a
Hi Neeraj,

After banging my head for quite a while, I've got it to work. It turns
out that the code isn't as beautiful as I would've liked, but frankly I
was fed up of Null Reference exceptions ~!!

Points to note :
---------------------
1. Copy and paste it into a Windows Form .vb file, and run Edit ->
Advanced -> Format Document. Don't try to view it here, since I have
removed all Tabs.
2. Add a Button named Button1 to your Form. This is needed only because
I start the processing at the click of the button.
3. I haven't used your code, since I had already progressed to some
extent with my own code, before your second post.
4. Hopefully, you can improve the code. I do hate repetitive code
statements, but in this case, it seemed necessary.
5. I have tried to comment inline, as much as possible, to allow you to
follow the program flow.
6. I have tested it with upto 5 levels of "menuItem" nesting.

================================
Imports System.Xml
Imports System.Xml.XPath
:
:
Dim xDoc As XmlDocument
Dim xNode As XmlNode
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
xDoc = New XmlDocument()
xDoc.Load("Input.xml")
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim xList As XmlNodeList = xDoc.SelectNodes("/menu/menuItem")
Try
For Each xNode In xList
ParseChildren(xNode)
Next
xDoc.Save("Output.xml")
MsgBox("Alrighty, then...")
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub

Private Sub ParseChildren(ByVal theNode As XmlNode)
Dim menuItemNode, subMenuNode As XmlNode
'Don't bother trying Text nodes.
If theNode.NodeType = XmlNodeType.Element Then
If theNode.HasChildNodes = True Then
menuItemNode = theNode.SelectSingleNode("./menuItem")
'Proceed only if any nested menuItem elements are present.
If Not (menuItemNode Is Nothing) Then
'Add a new "subMenu" node
subMenuNode = xDoc.CreateElement("subMenu")
AddToSubMenu(menuItemNode, theNode, subMenuNode)
'Repeat for any children menuItems
ParseChildren(subMenuNode.FirstChild)

'No more children menuItems are present for this node,
'so continue with next sibling.
menuItemNode = subMenuNode.NextSibling
'Parse for any child menuItems of this sibling
ParseChildren(menuItemNode)

While Not (menuItemNode Is Nothing)
AddToSubMenu(menuItemNode, theNode, subMenuNode)
menuItemNode = subMenuNode.NextSibling
End While
End If
End If
End If
End Sub

Private Sub AddToSubMenu(ByVal menuItemNode As XmlNode, ByVal
parentNode As XmlNode, ByVal SubMenuNode As XmlNode)
'Store the contents of this "menuItem" node in a DocFragment, including
the menuItem outer xml.
Dim frag As XmlDocumentFragment = xDoc.CreateDocumentFragment()
frag.InnerXml = menuItemNode.OuterXml
'Append contents of Frag.
SubMenuNode.AppendChild(frag)
parentNode.InsertBefore(SubMenuNode, menuItemNode)
parentNode.RemoveChild(menuItemNode)
End Sub
================================
Hope this helps,

Regards,

Cerebrus.

Mar 23 '06 #9

P: n/a
Hi Dickster,
My point really is this...
When iterating through each node in an XMlNodeList how do you know
where you are in the document hierarchy, in order to do this kind of insert
My answer : We (or atleast I) don't.

I think you have posed a very profound question. I thought XPath can
select nodes, but I don't know if it can be used to
insert/delete/append nodes.

The XPath: descendant::menuItem[parent::menuItem] will select all
"menuItem" elements in the document, which have a menuItem parent, as
you intended. Note that they may be at different levels of the
heirarchy. Inserting / Appending remains up to us. But as you correctly
realized, it seems quite a task to discover where the current
"menuItem" is in that heirarchy.
I had not thought of using the OuterXML property of XmlDocumentFragment
Cerebus -I am very interested to see how you do step 4/5/6.


Actually I have used the OuterXml property(ReadOnly) of the "menuItem"
node and assigned it to the InnerXml property of the
XmlDocumentFragment.

For the steps, refer to my answer to Neeraj.

And lastly, it's Cerebrus...with an "r" ;-))

Regards,

Cerebrus.

Mar 23 '06 #10

P: n/a
Hi,

I am facing one problem with the given code:

When i debug the code through breakpoints it is givng me the Output XML
Correctly. but when i running the code without debugging it fails to add in
some of last menuitems..

Can you please check this code on your machine.just provide input xml as the
input it will save output.xml on your C: drive.

Please help.

Thanks in Advance.

Regards,
Neeraj

Private Sub createXMLFile(ByVal xmlstring As String)
Dim objDoc As New System.Xml.XmlDocument
objDoc.LoadXml(xmlstring)
Dim objmenuItemNodeList As System.Xml.XmlNodeList
Dim objMenuNode As System.Xml.XmlNode
Dim menuitems As ArrayList
Dim counter As Integer
objmenuItemNodeList = objDoc.SelectNodes("//menuItem")

For Each objMenuNode In objmenuItemNodeList

If (checkChildMenuItems(objMenuNode)) Then
Dim objSubMenuNode As System.Xml.XmlNode =
objDoc.CreateNode(System.Xml.XmlNodeType.Element, "subMenu", "")

menuitems = menuItemsArrayList(objMenuNode)
For counter = 0 To menuitems.Count - 1

objSubMenuNode.AppendChild(DirectCast(menuitems(co unter), XmlNode))
Next
menuitems = Nothing
objMenuNode.AppendChild(objSubMenuNode)
End If
Next
Dim xmldecl As XmlDeclaration
xmldecl = objDoc.CreateXmlDeclaration("1.0", "utf-8", String.Empty)
objRootNode = objDoc.DocumentElement
objDoc.InsertBefore(xmldecl, objRootNode)
objDoc.Save("C:\outputXML.xml")
objDoc = Nothing
End Sub

Private Function checkChildMenuItems(ByVal sampleNode As XmlNode) As Integer
Dim returnvalue As Boolean
Dim i As Integer
returnvalue = False
For i = 0 To sampleNode.ChildNodes.Count - 1
If (sampleNode.ChildNodes(i).Name) = "menuItem" Then
returnvalue = True
Exit For
End If
Next
checkChildMenuItems = returnvalue
End Function
Private Function menuItemsArrayList(ByVal sampleNode As XmlNode) As
ArrayList
Dim returnvalue As New ArrayList
Dim i As Integer
For i = 0 To sampleNode.ChildNodes.Count - 1
If (sampleNode.ChildNodes(i).Name) = "menuItem" Then
returnvalue.Add(sampleNode.ChildNodes(i))
End If
Next
menuItemsArrayList = returnvalue
End Function

"ne*****@noida.nospamhcltech.com" wrote:
Hi Cerebrus,
Thanks for the reply.
Your understandign perfectly correct.
The logic which we have to apply is we have to insert subMenu tag whenever
menuItem is having the child menuItem and all the child menuItem tags should
be enclosed in subMenu tag.
Like in my input xml menuItem "REPORTS" is having two child meuItems
Standard Reports and Custom Reports. so they should be come into "subMenu"
tag. Also Now Custom Reports is also having 5 menuItem childs, so they should
be enclosed in one SubMenu Tag.

It's very simple that Reports is top level Menu
Standard Reports and Custom Reports are second level menu
Child under Standard reports are third level menu

You can see in my output xml
Currently i am using the following logic but i am not sure will it work for
any level of nesting

please help in providing the bugproof logic.

For Each objMenuNode In objmenuItemNodeList
If (checkChildMenuItems(objMenuNode)) Then
Dim objSubMenuNode As System.Xml.XmlNode =
objDoc.CreateNode(System.Xml.XmlNodeType.Element, "subMenu", "")
menuitems = menuItemsArrayList(objMenuNode)
For counter = 0 To menuitems.Count - 1

objSubMenuNode.AppendChild(DirectCast(menuitems(co unter), XmlNode))
Next
objMenuNode.AppendChild(objSubMenuNode)
End If
Next

************************************************** *******************************************
Private Function checkChildMenuItems(ByVal sampleNode As XmlNode) As Integer
Dim returnvalue As Boolean
Dim i As Integer
returnvalue = False
For i = 0 To sampleNode.ChildNodes.Count - 1
If (sampleNode.ChildNodes(i).Name) = "menuItem" Then
returnvalue = True
Exit For
End If
Next
checkChildMenuItems = returnvalue
End Function

************************************************** *********************************************
Private Function menuItemsArrayList(ByVal sampleNode As XmlNode) As
ArrayList
Dim returnvalue As New ArrayList
Dim i As Integer
For i = 0 To sampleNode.ChildNodes.Count - 1
If (sampleNode.ChildNodes(i).Name) = "menuItem" Then
returnvalue.Add(sampleNode.ChildNodes(i))
End If
Next
menuItemsArrayList = returnvalue
End Function
"Cerebrus" wrote:
Hi,

I'm not sure I understand you correctly, but I think you need to insert
a <subMenu> element before each nested <menuItem> element. In other
words, you want to convert input.xml so that it looks like output.xml
???

Is that so ? If so, could you post whatever logic you have come up with
till now ?

Regards,

Cerebrus.

Mar 24 '06 #11

P: n/a
Hi Cerebrus,

I am facing some new problem in the undermentioned code:

When i am running it in debug mode it's giving me correct Output CML with
submenu tags properly inserted but when i am runnign it with out debugging
it's skipping some of the last menuitems for adding submenus.

is it the memory issue..

just try to run this code on your machine and check in debugging as well as
without debugging you can understand the differences...

Just provide the input xml as as the input to the function.

Please help.I have already invested lot of the time in the issue but unable
to understand it.

Neeraj

*********************************************

Private Sub createXMLFile(ByVal xmlstring As String)
Dim objDoc As New System.Xml.XmlDocument
objDoc.LoadXml(xmlstring)
Dim objmenuItemNodeList As System.Xml.XmlNodeList
Dim objMenuNode As System.Xml.XmlNode
Dim menuitems As ArrayList
Dim counter As Integer
objmenuItemNodeList = objDoc.SelectNodes("//menuItem")

For Each objMenuNode In objmenuItemNodeList

If (checkChildMenuItems(objMenuNode)) Then
Dim objSubMenuNode As System.Xml.XmlNode =
objDoc.CreateNode(System.Xml.XmlNodeType.Element, "subMenu", "")

menuitems = menuItemsArrayList(objMenuNode)
For counter = 0 To menuitems.Count - 1

objSubMenuNode.AppendChild(DirectCast(menuitems(co unter), XmlNode))
Next
menuitems = Nothing
objMenuNode.AppendChild(objSubMenuNode)
End If
Next
Dim xmldecl As XmlDeclaration
xmldecl = objDoc.CreateXmlDeclaration("1.0", "utf-8", String.Empty)
objRootNode = objDoc.DocumentElement
objDoc.InsertBefore(xmldecl, objRootNode)
objDoc.Save("C:\outputXML.xml")
objDoc = Nothing
End Sub

Private Function checkChildMenuItems(ByVal sampleNode As XmlNode) As Integer
Dim returnvalue As Boolean
Dim i As Integer
returnvalue = False
For i = 0 To sampleNode.ChildNodes.Count - 1
If (sampleNode.ChildNodes(i).Name) = "menuItem" Then
returnvalue = True
Exit For
End If
Next
checkChildMenuItems = returnvalue
End Function
Private Function menuItemsArrayList(ByVal sampleNode As XmlNode) As
ArrayList
Dim returnvalue As New ArrayList
Dim i As Integer
For i = 0 To sampleNode.ChildNodes.Count - 1
If (sampleNode.ChildNodes(i).Name) = "menuItem" Then
returnvalue.Add(sampleNode.ChildNodes(i))
End If
Next
menuItemsArrayList = returnvalue
End Function
*********************************************
"Cerebrus" wrote:
Hi Dickster,
My point really is this...
When iterating through each node in an XMlNodeList how do you know
where you are in the document hierarchy, in order to do this kind of insert
My answer : We (or atleast I) don't.

I think you have posed a very profound question. I thought XPath can
select nodes, but I don't know if it can be used to
insert/delete/append nodes.

The XPath: descendant::menuItem[parent::menuItem] will select all
"menuItem" elements in the document, which have a menuItem parent, as
you intended. Note that they may be at different levels of the
heirarchy. Inserting / Appending remains up to us. But as you correctly
realized, it seems quite a task to discover where the current
"menuItem" is in that heirarchy.
I had not thought of using the OuterXML property of XmlDocumentFragment
Cerebus -I am very interested to see how you do step 4/5/6.


Actually I have used the OuterXml property(ReadOnly) of the "menuItem"
node and assigned it to the InnerXml property of the
XmlDocumentFragment.

For the steps, refer to my answer to Neeraj.

And lastly, it's Cerebrus...with an "r" ;-))

Regards,

Cerebrus.

Mar 24 '06 #12

P: n/a
Hi Neeraj,

I tried your code, and got a lot of errors. After correcting most of
them, I was able to generate the Output.xml file, and it does the job
for most of the MenuItems, except the last set within the HELP menu.

I do not think that a program will function differently, when run in
Debug mode and without Debugging. So, the problem must lie within the
logic. It runs the same for me with or without debugging.

Did you try the code I suggested ? Does it work or are you having
problems with that ?

Regards,

Cerebrus.

Mar 24 '06 #13

P: n/a
Hi Cerebrus (I'll get my spelling right from now on)

Apart from College I havent really used many recursive formulas so its
nice to see this one in action.

Its a good solution that answers alot of my questions & neerajb
question..
I'll post my question about position in the XDoc as a new thread see if
there is any response.

A code enhancement:
Probably move the 2nd recursive call to ParseChildren into the While
Loop - that way it handles imbedded menuitems in any of the siblings
(or at least it appeared to with the testing i did) - I stand to be
corrected

Private Sub ParseChildren(ByVal theNode As XmlNode)
Dim menuItemNode, subMenuNode As XmlNode

'Don't bother trying Text nodes.
If theNode.NodeType = XmlNodeType.Element Then

If theNode.HasChildNodes = True Then
menuItemNode = theNode.SelectSingleNode("./menuItem")

'Proceed only if any nested menuItem elements are
present.
If Not (menuItemNode Is Nothing) Then

'Add a new "subMenu" node
subMenuNode = xDoc.CreateElement("subMenu")
AddToSubMenu(menuItemNode, theNode,
subMenuNode)
'Repeat for any children menuItems
ParseChildren(subMenuNode.FirstChild)
'No more children menuItems are present for
this node,
'so continue with next sibling.
menuItemNode = subMenuNode.NextSibling

'Dickster: ParseChildren has been moved from
here into the While Loop
'immediatley below

While Not (menuItemNode Is Nothing)
ParseChildren(menuItemNode)
AddToSubMenu(menuItemNode, theNode,
subMenuNode)
menuItemNode = subMenuNode.NextSibling
End While

End If
End If
End If

Mar 24 '06 #14

P: n/a
Hi Dickster,

Thanks a lot, buddy, for that code enhancement. Actually I had tried to
put the ParseChildren statement into the While loop, exactly at the
position you did, but for some reason I got a Null reference exception
(again !).

Now, when I tried it again, it works !

I guess working on a programming problem at 4 am, *does* take it's toll
! ;-)
I'll post my question about position in the XDoc as a new thread see if
there is any response.


Yeah, I think that's the best way to get the experts on our problem...

Warm regards,

Cerebrus.

P.S.: I would like to keep up correspondence with you in the future, if
that's OK with you.

Mar 24 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.