Jump to content

XML list child node values of specific node


Recommended Posts

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
Link to comment
Share on other sites

$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.
Link to comment
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 )
Link to comment
Share on other sites

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.
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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.
Link to comment
Share on other sites

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
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.
Link to comment
Share on other sites

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.
Link to comment
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.

Link to comment
Share on other sites

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.
Link to comment
Share on other sites

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.
Link to comment
Share on other sites

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
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...