Sign in to follow this  
Followers 0
Tripredacus

XML list child node values of specific node

16 posts in this topic

#1 ·  Posted (edited)

This can't be so tough but I can't seem to get any results. My only experience with XML is with non-duplicate nodes, so I can't quite figure out how to get these values. I can do this with an INI file, but I would rather also know how to do it with XML as well.

I have a value that I need to search in XML, and display the value of the child nodes for it. Here is a sample XML file:

<?xml version="1.0"?>
<items>
    <item name="racecar">
        <type>value1</type>
        <type>value2</type>
    </item>
</items>

My code has been all over the place, I've tried so many thing, but this is what state it is left in:

#include <_XMLDomWrapper.au3>

Global $xml, $result, $n, $itemName

$itemName = "racecar"

$xml = _XMLFileOpen("c:cars.xml")

$result = _XMLGetNodeCount("/items/item/" & $itemName)
For $n = 1 to $result
    $a = _XMLGetValue("/items/item/" & $itemName[$n] & "/type")
    MsgBox (4096, $n, $a[1])
Next

So I am expecting to look in the XML for an item named "racecar" and have return

"value1"

"value2"

as the data. While I am using MsgBox here, I will eventually change that to be on a GUI.

Any ideas for me?

Edited by Tripredacus

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

$oXML=ObjCreate("Microsoft.XMLDOM")

$sFileLoc = "C:UsersjdelaneyDesktoptest.xml"

$oXML.load ( $sFileLoc )

$stest = $oXML.selectSingleNode( "//items" )

MsgBox ( 4096,"test", $stest.text )

There we go...just look into all the properties, and you can drill in to what you need

sample xpath for your intended: //items/item[@name="racecar"]/type[0]

//items/item[@name="racecar"]/type[1]

updated, they are 0 based.

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

This is kinda helpful but it isn't working. The example you posted works, however there is no input for the object's name. It just shows the values of the item nodes. This is fine except that I am starting small with only a single parent object just so I can figure this out. If I add another item to the XML, it ignores that one totally, not showing its values. Any time I try to specify searching the XML for an object named by the variable, and put that into an output (MsgBox) I get:

The requested action with this object has failed.

Example:

$oXML = ObjCreate("Microsoft.XMLDOM")
$sFileLoc = "c:cars.xml"
$oXML.load ( $sFileLoc )

$result = $oXML.SelectSingleNode ( "//items/item[@name=" & $itemName & "]/type[0]")
MsgBox(4096, "test", $result.text )

Share this post


Link to post
Share on other sites

$ItemName is defined in my first post. Its a static variable for testing purposes only. In my second post, I didn't paste the part with the includes, declarations and definitions. Those are the same.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

You need to include " surrounding to be a valid xpath...so change it to:

$result = $oXML.SelectSingleNode ( '//items/item[@name="' & $itemName & '"]/type[0]')
Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

OK this works but is in an endless loop. SelectSingleNode doesn't look like it is the correct method since it only grabs the first "type" node and ignores the rest. Although after clicking OK on the messagebox it pops back up with the same value until I kill the app.

It appears that I should be using SelectNodes instead, however how do I format this into AutoIT? Here is the MSDN example:

nodeList = root.SelectNodes("//book[contains(title,""'Emma'"")]")

SciTE doesn't like all those quotes in there. I tried this:

$result = $oXML.SelectNodes ( '//items/item[@name="' & $itemName & '"]/type[contains(title,"value")]')

Updated XML example...

<?xml version="1.0"?>
<items>
        <item name="racecar">
                <type title="value1">value1</type>
                <type title="value2">value2</type>
        </item>
</items>

I'll work on this some more after lunch.

Edited by Tripredacus

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

ok, so you will need something like this...i'll play around with the syntax in a bit, not sure if this will run:

[font=monospace]
$result = $oXML.SelectNodes ( '//items/item[@name="' & $itemName & '"]/type[contains(title,"value")]')
$iUBound = $result.length

For $i=0 to $iUBound ; (might need  $iUBound-1, not sure if this is 0 based...probably 1 based)
   msgbox(4096, "test", $result[$i].text)
Next
Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

done (i saved your xml to the give file):

$oXML=ObjCreate("Microsoft.XMLDOM")
$stest = FileRead("c:usersjdelaneydesktoptest2.xml")
$oXML.LoadXML($stest)
ConsoleWrite ( $oXML.xml & @CRLF)
$itemName = "racecar"

$result = $oXML.selectNodes( '//items/item[@name="' & $itemName & '"]/type[@title="value"]' )
$iUBound = $result.length
ConsoleWrite ( $result.length & @CRLF )
For $Node In $result
  msgbox(4096, "test", $Node.text)
Next
Edited by jdelaney
1 person likes this

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

notice i droped the contains...i think that's an issue with autoit...

both of these are legit xpaths, but don't work through autoit

$result = $oXML.selectNodes( '//items/item[@name="' & $itemName & '"]/type[contains(@title,"value")]' ) ; this is the attribute @title contains value

and:

$result = $oXML.selectNodes( '//items/item[@name="' & $itemName & '"]/type[contains(.,"value")]' ) ; this is the type node contains value

and this is the third one...no go:

$result = $oXML.selectNodes( '//items/item[@name="racecar"]/type/@title[contains(.,"value")]' ) ; this is the attribute @title contains value

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

That gives me a good starting point. I confirmed that my example works.

So for discussions sake, those two examples using "contains" do not work with AutoIT using DOM or even with the _XMLDomWrapper?

Share this post


Link to post
Share on other sites

I've never used/attempted-to-use, the _XML UDF functions, but using the DOM, no go.


IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

Ok one other question, finding this in the DOM documentation isn't going well. I had to make a change to my XML to give the title= a unique value. I know that I can get the value of the node by using the .text, but where is a list of these types of outputs? Getting the .text return is great, however I also need to store the title= value in a variable too. Here is my updated code (I ended up using selectSingleNode too, thanks for that one! )

Global $xml, $result, $n, $itemName

$itemName = "racecar"

$oXML = ObjCreate("Microsoft.XMLDOM")
$sFileLoc = "f:cars.xml"
$oXML.load ( $sFileLoc )

$stest = $oXML.selectSingleNode( '//items/item[@name="' & $itemName & '"]')
If IsObj($stest) Then
    $result = $oXML.SelectNodes ( '//items/item[@name="' & $itemName & '"]/type')
     For $n In $result
            MsgBox(4096, "test", $n.text )
        Next
ElseIf Not IsObj($stest) Then
    MsgBox (4096, "boo", "car not found")
EndIf

I modified my test xml above to have a unique value for title.

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

ok, where the title is the attribute of the node...you need to specifically call that attribute out.

For $Node In $result ; (might need  $iUBound-1, not sure if this is 0 based...probably 1 based)
$oAttribute = $Node.selectSingleNode('[email=""]//@title[/email])
msgbox(4096, "test", $oAttribute.text )
msgbox(4096, "test", $Node.text)
Next

autoformating :/ $oAttribute = $Node.selectSingleNode(//@title)

I can't add literal text, but know the innerstring of (), is surrounded by "

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

this is cleaner...to loop through all attributes, and you can add your own logical statements:

For $Node In $result
$oAttributes = $Node.attributes
For $oAttribute In $oAttributes
  msgbox(4096, "test", $oAttribute.text )
Next
msgbox(4096, "test", $Node.text)
Next
Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

Thanks, I'll take a look at this tomorrow.

This lets me use both in the same MsgBox.

For $Node In $result
            $oAttributes = $Node.Attributes
            For $oAttribute In $oAttributes
            MsgBox(4096, $oAttribute.text, $Node.text )
            Next
        Next
Edited by Tripredacus

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0