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

Problems with iteration of IXMLDOMNodeList

P: n/a
I have a problem that I can't work out. I have a script in ASP using VBScript that act quite funny when editing and xml file. Here is my explenation

I have the following xml-fil

<root><element type="type1">element 1</element><element type="type1">element 2</element><element type="type1">element 3</element><element type="type2">element 4</element><element type="type2">element 5</element></root

I wanted to order them by type, by creating a new node for each type in the root element and then inserting the corresponding elements into the type node. The output should be looking like this

<root><type1><element type="type1">element 1</element><element type="type1">element 2</element><element type="type1">element 3</element></type1><type2><element type="type2">element 4</element><element type="type2">element 5</element></type2></root

Now, when doing this I first got all the element nodes into an IXMLDOMNodeList, I used the method .getElementsByTagName( "element" ). No problem there. Since I don't like to use "For X = 0 To Y" I used "For Each X In Y" instead, where Y was the IXMLDOMNodeList
Then, within the loop i took the current Nodes parent and appended a child to it with the type as the nodeName, if the type was different from the last nodes type. Then I kept adding current node to the nodes parents last child, which resulted in me moving the elements into the correct type node

When doing this the first time i printed the length of the IXMLDOMNodeList at the beginning of the file, but when i removed it everything went crazy. It seems that when I dodn't check the length (either by responsing it or just by setting a "dumb" variable to it) the loop went on forever. I read that the IXMLDOMNodeList was live and that got me thinking that for each loop the referense to .getElementsByTagName was run and it would keep finding new ones. But that still dowesn't explain why it worked when geting the length of it first hand. I later on tried the "For X = 0 To IXMLDOMNodeList.length -1" approach and that worked fine since i called upon the length property
Then I got back to the "For Each X In Y" code and added a exact copy of the enumeration before the orgininal one, without doing anything, and that seemed to "lock" the length and worked fine. This got me really confused

The last thing I tried was to use the selectNodes method where i specifically got the "/root/element" nodes and that turned out great. When using "//element" as the XPath the script acted as when I use the .getElementsByTagName approach. I stuck with this just to get moving but I am still not up to speed what was going on. Is this a bug or is it supposed to re-run the search every iteration when using "For Each X In Y"

Please, put me at ease and explain this to me. I used DOMDocument.3.0

Many thanks in advance
Martin Danielson
Jul 19 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
Martin Danielson wrote:
I have a problem that I can't work out. I have a script in ASP using
VBScript that act quite funny when editing and xml file. Here is my
explenation:

I have the following xml-file

<root><element type="type1">element 1</element><element
type="type1">element 2</element><element type="type1">element
3</element><element type="type2">element 4</element><element
type="type2">element 5</element></root>

I wanted to order them by type, by creating a new node for each type
in the root element and then inserting the corresponding elements
into the type node.


Well, you are doing it the hard way. Here is a function (actually, two
functions) from my code library that I wrote for re-ordering an xml
document. See if you can adapt it to your needs:

function SortXMLdocBySingleElement(pxmlDoc,psEl, _
psType, psDirection)
'************************************************* ***
'Pass an xml document, an element name, a datatype name
'(Integer, String, Long, Double, Single, or Date) and a direction
'(ASC or DESC). Usage example:
' set xmldoc=SortXMLdocBySingleElement(xmldoc, _
' "MyElement","String","ASC")
'************************************************* ***
dim i, j,lChildNodes, vCurVal, vNewVal, oRoot
dim oReplacedNode, oNode, oNewNode
dim xmldoc
set xmldoc = pxmldoc
set oRoot = xmldoc.documentelement
lChildNodes=oRoot.childnodes.length

for i = 0 to lChildNodes - 2
set oNode = oRoot.childnodes(i)
vCurVal = ConvertToSpecifiedType(oNode.selectsinglenode(psEl ).text,psType)
for j = i + 1 to lChildNodes - 1
set oNewNode = oRoot.childnodes(j)
vNewVal =
ConvertToSpecifiedType(oNewNode.selectsinglenode(p sEl).text,psType)
if psDirection = "ASC" Then
if vNewVal < vCurVal then
set oReplacedNode =
oRoot.insertbefore(oRoot.childnodes(j),oRoot.child nodes(i))
vCurVal = vNewVal
end if
else
if vNewVal > vCurVal then
set oReplacedNode =
oRoot.insertbefore(oRoot.childnodes(j),oRoot.child nodes(i))
vCurVal = vNewVal
end if
end if
next
next
Set SortXMLdocBySingleElement = xmldoc
end function

function ConvertToSpecifiedType(pvData,psType)
Select Case psType
case "Integer": ConvertToSpecifiedType = CInt(pvData)
case "String": ConvertToSpecifiedType = CStr(pvData)
case "Long": ConvertToSpecifiedType = CLng(pvData)
case "Double": ConvertToSpecifiedType = CDbl(pvData)
case "Single": ConvertToSpecifiedType = CSng(pvData)
case "Date": ConvertToSpecifiedType = CDate(pvData)
end select
end function
There are also techniques using xsl transformations that can make short work
of this. A Google search should turn up some examples.

HTH,
Bob Barrows
--
Microsoft MVP - ASP/ASP.NET
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"
Jul 19 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.