Sign in to follow this  
Followers 0
gillesg

[Solved] Xml Parsing - with XMLDOM

5 posts in this topic

#1 ·  Posted (edited)

Hi All,

I Am trying to update field in a xml file ("iTunesPrefs.xml" see attach)

To do so, I try to use XMLDOM (link : )

So far I am unsuccesfull.

Here is the code I came up to, and I am stuck.

#Include <File.au3>
#Include <Array.au3>
#include "_XMLDomWrapper.au3"

$DirInput =@TempDir
$FileInput = "iTunesPrefs.xml"

$sXmlFile =$DirInput & "\" & $FileInput
$iOXml = _XMLFileOpen($sXmlFile)
$XmlRootPath = "//plist/dict"

Local $i_Nodes = _XMLGetNodeCount ( $XmlRootPath)
msgbox(0,"","nb node = " & $i_Nodes)
If $i_Nodes > 0 Then
Local $sRet = _XMLGetChildNodes ( $XmlRootPath)
$i_nodes=$sRet[0]
msgbox(0,"","nb node = " & $i_Nodes)

Local $nodeIndex, $key[$i_Nodes], $value[$i_nodes], $z
If IsArray($sRet) Then
_ArrayDisplay($sRet,"Node Names with _XMLGetChildNodes")
$aArr = _XMLGetField ($XmlRootPath)
_arraydisplay($aArr)
For $nodeIndex = 1 To $sRet[0]
$key[$nodeIndex - 1] = _RetFirst(_XMLGetField ($XmlRootPath & "[" & $nodeIndex & "]"))
$value[$nodeIndex - 1] = "<" &$sRet[$nodeIndex] & ">" & _RetFirst(_XMLGetField ($XmlRootPath & "[" & $nodeIndex & "]"))
Next
_ArrayDisplay($key, "Key")
_ArrayDisplay($Value, "Value")
EndIf
EndIf
Exit

;===============================================================================
;Funcs
;===============================================================================
Func _RetFirst($aArray); return first item in an array
If IsArray($aArray) Then
if $aArray[0] >=1 then
Return $aArray[1]
Else
Return $aArray[0]
EndIf
EndIf
EndFunc ;==>_RetFirst

I want to navigate thru each XML node and manipulate its Xml Tag Name and value.

Especialy I want to update the Value of the Data field after the "<key>iTunes Library XML Location:1</key>"

Can anyone give me some hints or advices ? I am lost.

Regards.

iTunesPrefs.xml

Edited by gillesg

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Please provide the XPath, or a snippet of the XML.

$oXML=ObjCreate("Microsoft.XMLDOM")
;$stest = @DesktopDir & "xml1.xml"
$oXML.LoadXML('<td class="questionTitle"><a href="testing an attribute.html" class="asdf" >asdf</a></td>') ; load text of the DOM object
;$oXML.load($stest) ; load file of xml
ConsoleWrite ( $oXML.xml & @CRLF)
$result1 = $oXML.selectSingleNode('//a')
$result1.text = "whatever you want it to be"
ConsoleWrite ( $oXML.xml & @CRLF)

this will change the value of the //a node/

One more sample, to loop through nodes:

$result = $oXML.selectNodes( '//items/item[@name="test"]/type[contains(@title,"value")]' )
For $Node In $result
 If $node.text = "whatever your condition is" Then
  $node.text = "whatever value you need"
 EndIf
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

Please provide the XPath, or a snippet of the XML.

...

Hi,

Thanks for the fast response. The XML file that I try to parse is attached to the first post.

I will dig into your sample to see it if i am able to work it out.

Regards,

Gilles

Share this post


Link to post
Share on other sites

Hi,

After digging into the proposition, I realized that my problem was not knowing what "XPATH" was.

I used the following ressources to get a basic understanding and fix what I needed :

http://www.zvon.org/comp/r/ref-XPath_2.html#intro

Detailled XPATH-2 possibilities

http://www.zvon.org/xxl/XPathTutorial/General/examples.html

XPATH-1 tutorial

http://stackoverflow.com/questions/1198253/xpath-how-to-select-elements-based-on-their-value

Some answers from the web

And finally my code now looks like :

; Script Start - Add your code below here
#Include
#Include
#include "Base64.au3"
#include "_XMLDomWrapper.au3"

$DirInput = "C:\Users\ggros\Personnel\Réflexion codage"
$FileInput = "iTunesPrefs.xml"

$sXmlFile =$DirInput & "\" & $FileInput
$iOXml = _XMLFileOpen($sXmlFile)

$XmlRootPath = '//plist/dict/dict/key[starts-with(text(),"iTunes Library XML Location")]/following::data[position()=1]'

;iTunes Library XML Location
Local $i_Nodes = _XMLGetNodeCount ( $XmlRootPath)
If $i_Nodes = 1 Then
$aArrayValue = _XMLGetValue($XmlRootPath)
_arraydisplay($aArrayValue,"_XMLGetValue")

_XMLUpdateField($XmlRootPath,"The New data that need to be set ")
$abArr = _XMLGetValue($XmlRootPath)
_arraydisplay($abArr,"_XMLGetValue")
EndIf
Exit

The magic lies here :

$XmlRootPath = '//plist/dict/dict/key[starts-with(text(),"iTunes Library XML Location")]/following::data[position()=1]'

Regards,

Gilles

Share this post


Link to post
Share on other sites

Hi gillesg,

Were you able to get this working? I'm also looking for a way to set the Itunes xml file location.

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

  • Similar Content

    • SJF85
      By SJF85
      Hey, just wondering if anyone has ever encountered intermittent COM Object Errors with Microsoft.XMLDOM pulling node values. I'm currently getting "Bad Variable Type" intermittently, and simply running the script again would allow it to get further in the parsing loop, only to encounter the error again. The data is persistent, and it is always a string.
      Here's a snippet of where the error event occurs
      $Target = "Item001" $SearchItem = $oXML.SelectNodes("//Items/Name[. = """&$Target&"""]") If $SearchItem.Length==1 Then AddToLog("XML: Found a match for """&$Target&""", Gathering details...") $TargetItem = $SearchItem.Item(0).ParentNode $ItemSKU = XMLGetValue($TargetItem, "SKU") Endif and here's the snip of my XMLGetValue function where the error is always triggered on the $Value = ...
      Func XMLGetValue($Node="", $ValueName="", $NestLevel=0) ... If $Node.GetElementsByTagName($ValueName).Item(0).ChildNodes.Length==1 Then $Value = $Node.GetElementsByTagName(String($ValueName)).Item(0).ChildNodes(0).NodeValue Else ...Tell me there are more than one result for the target Endif ... EndFunc I added the string() as a counter measure but that doesnt fix the error. The XML file contains standard data with no attributes or anything funky.
      The weird thing is that if i reboot my workstation it might get all the way through, and then if i run it again it may burp some where throughout the loop process (For each item, get SKU, Add SKU to array, Do stuff with array contents afterwards). 
      I have added sleep timers to my loops to try and pace the XML requests in case it was a sort of buffer underrun issue but im not certain whats going on.
       
      Again, i could run the script and it would work perfectly and then fail another time. I've read up about readyState, but i dont know how to incorporate it in my script.
      Has anyone seen this before? Thanks in advance for your help.
       
    • Simpel
      By Simpel
      Hi. I'm trying to write a xml. Here is my code:
      #include <_XMLDomWrapper.au3> #include <Date.au3> Global $g_sXMLFileName Global $g_sDestPath = @DesktopDir & "\" Global $g_sReturnedBID = "A10829" _makeXML() _AddXML(1, "A10829_Thomas/wav/T001.wav") _AddXML(2, "A10829_Thomas/wav/T002.wav") Exit Func _makeXML() Local $sXMLtime = StringReplace(StringReplace(StringReplace(_NowCalc()," ","_"),":","-"),"/","-") ; in yyyy-mm-dd_hh-mm-ss $g_sXMLFileName = $g_sDestPath & $g_sReturnedBID & "_" & "EB-Ton-Upload" & "_" & $sXMLtime & ".xml" _XMLCreateFile($g_sXMLFileName, "gemagvl", 1,1) _XMLFileOpen($g_sXMLFileName) EndFunc Func _AddXML($iCount, $sDateiname) _XMLCreateRootNodeWAttr("row", "count", $iCount, "") _XMLCreateChildNode("//row", "picklistenname", $g_sReturnedBID & "_EB-Ton-Upload") _XMLCreateChildNode("//row", "picklisteninfo") _XMLCreateChildNode("//row", "bid", $g_sReturnedBID) _XMLCreateChildNode("//row", "audiodateiname", $sDateiname) _XMLCreateChildNode("//row", "titel", StringTrimRight(StringTrimLeft($sDateiname, 7), 4)) _XMLCreateChildNode("//row", "interpret", "EB") _XMLCreateChildNode("//row", "quelle", "Ton") EndFunc It returns:
      <?xml version="1.0" encoding="UTF-8"?><gemagvl> <row count="1"> <picklistenname>A10829_EB-Ton-Upload</picklistenname> <picklisteninfo/> <bid>A10829</bid> <audiodateiname>A10829_Thomas/wav/T001.wav</audiodateiname> <titel>Thomas/wav/T002</titel> <interpret>EB</interpret> <quelle>Ton</quelle> <picklistenname>A10829_EB-Ton-Upload</picklistenname> <picklisteninfo/> <bid>A10829</bid> <audiodateiname>A10829_Thomas/wav/T002.wav</audiodateiname> <titel>Thomas/wav/T003</titel> <interpret>EB</interpret> <quelle>Ton</quelle> </row> <row count="2"> <picklistenname>A10829_EB-Ton-Upload</picklistenname> <picklisteninfo/> <bid>A10829</bid> <audiodateiname>A10829_Thomas/wav/T002.wav</audiodateiname> <titel>Thomas/wav/T003</titel> <interpret>EB</interpret> <quelle>Ton</quelle> </row> </gemagvl> But it should return:
      <?xml version="1.0" encoding="UTF-8"?><gemagvl> <row count="1"> <picklistenname>A10829_EB-Ton-Upload</picklistenname> <picklisteninfo/> <bid>A10829</bid> <audiodateiname>A10829_Thomas/wav/T001.wav</audiodateiname> <titel>Thomas/wav/T002</titel> <interpret>EB</interpret> <quelle>Ton</quelle> </row> <row count="2"> <picklistenname>A10829_EB-Ton-Upload</picklistenname> <picklisteninfo/> <bid>A10829</bid> <audiodateiname>A10829_Thomas/wav/T002.wav</audiodateiname> <titel>Thomas/wav/T003</titel> <interpret>EB</interpret> <quelle>Ton</quelle> </row> </gemagvl> The second inserted nodes are double. How will it be going right?
      Regards, Conrad
    • rootx
      By rootx
      I need help to read in a loop the DVD id child and subchild. Thx
      Example...
      DVD001 - PAL - EN,FR,DE,ES,IT and filter the right title & descri language.  I tried with $oXML.SelectSingleNode but without success
      <?xml version="1.0" encoding="UTF-8"?> <datafile xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mydvd.xsd"> <dvd name="My dvd title"> <id>DVD001</id> <region>PAL</region> <languages>EN,FR,DE,ES,IT</languages> <locale lang="EN"> <title>title en</title> <descri>descri en</descri> </locale> <locale lang="FR"> <title>title fr</title> <descri>descri fr </descri> </locale> <locale lang="DE"> <title>title de</title> <descri>descri de </descri> </locale> <locale lang="ES"> <title>title es</title> <descri>descri es</descri> </locale> <locale lang="IT"> <title>title it</title> <descri>descri it</descri> </locale> </dvd> <dvd name="My dvd title 2"> <id>DVD002</id> <region>USA</region> <languages>EN</languages> <locale lang="EN"> <title>title en</title> <descri>descri en</descri> </locale> </dvd> </datafile> #include <File.au3> $xml = @ScriptDir&"\test.xml" Local $oXML = ObjCreate("Microsoft.XMLDOM") $oXML.load($xml) $id = $oXML.SelectNodes("//dvd") For $ids In $id ConsoleWrite($ids.text &@CRLF) Next  
    • mLipok
      By mLipok
      I was asking @eltorro serveral times for any support  for XML DOM wrapper (COM) - with no success  
          So I took matters into my hands ..... I want to present XMLWrapperEx.au3 - BETA Version
      Want to join to the project ?
       
      Here is some description:
      ; #INDEX# ======================================================================================================================= ; Title .........: XMLWrapperEx.au3 ; AutoIt Version : 3.3.10.2++ ; Language ......: English ; Description ...: Functions to use for reading and writing XML using msxml. ; Remarks .......: BETA Version ; Author ........: mLipok ; Version .......: "1.1.1.01" ; _XML_MiscProperty_UDFVersion() #CS This UDF is created on the basis of: https://www.autoitscript.com/forum/topic/19848-xml-dom-wrapper-com/ For this reason, I attach also the last known (to me) previous version ($_XMLUDFVER = "1.0.3.98" _XMLDomWrapper_1.0.3.98_CN.au3 ) For the same reason I continue to recognize the achievements of the work of my predecessors (they are still noted in each Function header). . . . . !!!!!!!!! This is BETA VERSION (all could be changed) !!!!!!!!! . . . WORK IN PROGRES INFORMATION: For now 2015-09-01 the descripion (Function Header) can not entirely correctly describe the function. TODO: in many places I used "TODO" as a keyword to find what should be done in future . I want to: PREVENT THIS: The unfortunate nature of both the scripts is that the func return results are strings or arrays instead of objects. .     I want to: USE THIS CONCEPT:     .   All function should use Refernce to the object as first Function parameter     .   All function should return in most cases objects. There should be separate functions to Change Object collection to array     .   All function should use COM Error Handler in local scope.     .   All function should return @error which are defined in #Region XMLWrapperEx.au3 - @ERROR Enums     .    All function should have the same naming convention     .    All variables should have the same naming convention     .    There should not to be any Global Variable - exception is $g__oXMLDOM_Events     .   It should be possible easy to use XML DOM Events     .        https://msdn.microsoft.com/en-us/library/ms764697(v=vs.85).aspx     .   It should be possible easy to Debug     .    Ultimately, you should be able to do anything with your XML without having to use your own Error Handler. #CE  
      More info inside zip archive.
      This UDF can be downloaded from here:
      REMARK:
      This UDF was formerly named:   XMLWrapperEx.au3 
       
    • 31290
      By 31290
      Hi Guys, 
      Since I'm able to get a Dell equipment warranty status thanks to my API key, I'm using an UDF to extract data from an XML file and get the end date. > 
      Thing is, when using InetGet, the original file is in JSON format and the UDF is not working anymore, even if I download the file with the xml extension. Therefore, and when I manually download the page with Chrome, I have a proper XML file where the UDF is working fine.
      Here's my code:
      I even tried to convert the json to xml > https://www.autoitscript.com/forum/topic/185717-js-json-to-xml/
      I took a look here https://www.autoitscript.com/forum/topic/104150-json-udf-library-fully-rfc4627-compliant/ but I don't understand anything :/
       
      The XML read UDF is just perfect for my needs but I'm stuck here... 
      Thanks for any help you can provide
      -31290-
      3MTXM12.json
      3MTXM12.xml