notta Posted August 17, 2009 Posted August 17, 2009 (edited) If I had an XML file with the following structure how can I loop through the nodes returning value 'a' when 'value' equals a certain value? Let's say I wanted all the values of 'a' when 'value' = 9. I would get 20, 7, 88, 34. <test> <n1 a="20" b="1" value="9"/> <n1 a="22" b="134" value="6"/> <n1 a="18" b="12" value="4"/> <n1 a="7" b="13" value="9"/> <n1 a="44" b="155" value="12"/> <n1 a="6" b="155" value="10"/> <n1 a="88" b="1" value="9"/> <n1 a="34" b="65" value="11"/> <n1 a="34" b="12" value="9"/> <n1 a="20" b="87" value="8"/> </test> The thing that is throwing me is that all my nodes are named the same,but it's too late to go back and change that now. Everything I come upwith only returns the last node in the tree. Thanks. Edited August 18, 2009 by notta
lulupepe Posted August 19, 2009 Posted August 19, 2009 Hello, I've been struggling to extract the content from <names> from the following XML, for days. Thanks No luck with .... _GetFirstValue('/life-balance-exchange/outline/task/name') ;Get the first real value returned from the _XMLGetValue() return array. Func _GetFirstValue($node) $ret_val = _XMLGetValue($node) If IsArray($ret_val) Then Return ($ret_val[1]) Else Return SetError(1,3,0) EndIf EndFunc XML: <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <life-balance-exchange> <outline> <task effort="1.0" importance="0.1"> <name>task1</name> <anywhere/> <task> <name>subtask2</name> <place name="zDelia"/> <byDueDate dueDate="2009-08-19T09:00:00" leadTime="PT8H"/> <note>notes</note> </task> <task> <name>subtask3</name> <task effort="1.6"> <name>Subtask3.1</name> <place name="zDelia"/> </task> </task> </task> </outline> <places> <place name="zDelia"> <alwaysClosed/> </place> </places> </life-balance-exchange>
roze Posted September 13, 2009 Posted September 13, 2009 Sorry for my stupid question, but I'm not to able get a node 'gsak:Parent' from my XML file -> <gpx> <wpt lat="50.067" lon="14.382867"> <name>SA10ZVF</name> <cmt>Misto k zaparkovani a startovaci pozice pro lov</cmt> <type>Waypoint|Parking Area</type> <extensions> <gsak:wptExtension xmlns:gsak="http://www.gsak.net/xmlv1/3"> <gsak:Parent>GC10ZVF</gsak:Parent> <gsak:Child_ByGSAK>false</gsak:Child_ByGSAK> </gsak:wptExtension> </extensions> </wpt> </gpx> Thank you for your advice.
BigGrayBeast Posted September 23, 2009 Posted September 23, 2009 I'm trying to parse an Atom file from Google Reader. It is all my Google Reader Starred items. I have used _XMLGetValue() successfully in another project to get data from an XML file, but the complication of name spaces here is throwing me. Can someone amend this code to make it work? #include <_XMLDomWrapper.au3> #include <File.au3> #include <Array.au3> dim $xmlFile = "C:\Documents and Settings\Mark\My Documents\My Dropbox\Google Reader Parse\g2en.xml" $oOXml = _XMLFileOpen($xmlFile) $XML_Path = "Not sure what to put in here" ; I'm aiming to recover the Name value (author's name), as an example. $arrayx = _XMLGetValue($XML_Path) _ArrayDisplay($arrayx,"Author's Name") The XML file from Google Reader: <?xml version="1.0" ?> - <feed xmlns:idx="urn:atom-extension:indexing" xmlns:gr="http://www.google.com/schemas/reader/atom/" xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom" idx:index="no"> - <!-- Content-type: Preventing XSRF in IE. --> <generator uri="http://www.google.com/reader">Google Reader</generator> <id>tag:google.com,2005:reader/user/My Google Reader ID Blocked out here/state/com.google/starred</id> <title>Mark's starred items in Google Reader</title> <gr:continuation>CKv3_pKc_5wC</gr:continuation> <link rel="self" href="http://www.google.com/reader/atom/user%2FMy Google Reader ID Blocked out here/state/com.google/starred" /> - <author> <name>Mark</name> </author> <updated>2009-09-22T11:48:45Z</updated> - <entry gr:crawl-timestamp-msec="1253620125221"> <id gr:original-id="http://smarterware.org/?p=3296">tag:google.com,2005:reader/item/5616f8f931476bfc</id> <category term="user/My Google Reader ID Blocked out here/state/com.google/read" scheme="http://www.google.com/reader/" label="read" /> <category term="user/My Google Reader ID Blocked out here/state/com.google/starred" scheme="http://www.google.com/reader/" label="starred" /> <category term="user/My Google Reader ID Blocked out here/state/com.google/tracking-mobile-read" scheme="http://www.google.com/reader/" label="tracking-mobile-read" /> <category term="user/My Google Reader ID Blocked out here/state/com.google/fresh" scheme="http://www.google.com/reader/" label="fresh" /> <category term="Hardware" /> <category term="Mobile" /> <category term="battery life" /> <category term="laptops" /> <category term="Twitter" /> <category term="Twitter Q&A" /> <title type="html">Unplug Your Laptop Regularly (When In Doubt)</title> <published>2009-09-22T06:12:13Z</published> ... (rest of entry here, followed by many more entries) </entry> </feed> Thank you for any and all help. Mark
mrmacadamia Posted September 29, 2009 Posted September 29, 2009 It could be nice if someone can post some example for this udf since the link(_XMLExample.au3) is broken.
weaponx Posted October 2, 2009 Posted October 2, 2009 I'm trying to parse an Atom file from Google Reader. It is all my Google Reader Starred items. I have used _XMLGetValue() successfully in another project to get data from an XML file, but the complication of name spaces here is throwing me. Can someone amend this code to make it work? First problem, it looks like you copied the xml from the browser window instead of the page source. This leaves dashes at the beginning of some tags. Second problem, the ampersand character has to be escaped for the xml to parse: <category term="Twitter Q&A" /> needs to be <category term="Twitter Q&A" /> And finally, the source xml has a default namespace specified with no identifier ( xmlns="http://www.w3.org/2005/Atom"). This must be overridden using a specific identifier when the file is opened. Code #include "_XMLDomWrapper.au3" $sXMLFile = "Untitled-1.xml" $result = _XMLFileOpen($sXMLFile, 'xmlns:idx="urn:atom-extension:indexing" xmlns:gr="http://www.google.com/schemas/reader/atom/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:test="http://www.w3.org/2005/Atom"') If $result = 0 Then MsgBox(0,"","File not found") Exit EndIf $result = _GetFirstValue("//test:author/test:name") If @ERROR Then ConsoleWrite("@ERROR: " & @ERROR & @CRLF) Else ConsoleWrite($result & @CRLF) EndIf ;_XMLGetValue returns an array (not sure why) this will return the first element Func _GetFirstValue($node) $ret_val = _XMLGetValue($node) If IsArray($ret_val) Then Return ($ret_val[1]) Else Return SetError(1,3,0) EndIf EndFunc You can see when I call _XMLFileOpen I include the namespaces, this is copied from the XML file. I only change this: xmlns="http://www.w3.org/2005/Atom" to xmlns:test="http://www.w3.org/2005/Atom" The identifier used here has to be appended to all nodes in your xpath. Don't ask me why, it just works.
BigGrayBeast Posted October 2, 2009 Posted October 2, 2009 Thanks Weaponx. I'll digest this over the weekend. Should be what I needed.
ayr Posted October 5, 2009 Posted October 5, 2009 Hello, I am new to XML files. I've been reading this thread for quite a while now and collecting more and more information. I've been also using some external resources like w3schools.com to get to know structure and other aspects of XML. When it comes to working on my own with AutoIt and XML DOM wrapper - I still lack basics in transferring XML file structure in logical and accessible way that would fit my needs. I need your help! Here is my XML: expandcollapse popup<?xml version="1.0" encoding="UTF-8" ?> <MOVIE> <Drama> <Mov Name="Drama1" Length="120" Country="USA" /> <Medium> <Type>ALL</Type> </Medium> <Rating> <Mark>G</Mark> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>SE1</Branch> <Branch>NE2</Branch> </Store> <Available>YES</Available> </Drama> <Drama> <Mov Name="Drama2" Length="90" Country="UK" /> <Medium> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>NR</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>NO</Available> </Drama> <Comedy> <Mov Name="Comedy1" Length="160" Country="USA" /> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>R</Mark> <Mark>NC17</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Comedy> <Comedy> <Mov Name="Comedy2" Length="80" Country="France" /> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> </Medium> <Rating> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>NW1</Branch> <Branch>NE3</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Comedy> <Action> <Mov Name="Action1" Length="100" Country="USA" /> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> </Medium> <Rating> <Mark>R</Mark> <Mark>NC17</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>NE3</Branch> </Store> <Available>NO</Available> </Action> <Action> <Mov Name="Action2" Length="120" Country="Australia" /> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>NW1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Action> </MOVIE> What I need to do is: 1. Display presented XML in tree view like list on the screen. 2. Display order is based on genre like in this example: Drama, Comedy, Action. 3. Under each genre appropriate movies should be listed based on attribute 'Name' - for instance Drama1 under Drama. 4. I need to go over rest of attributes and nodes and somehow store them in order to do some background work. I appreciate all advices. Thanks in advance, ayr
weaponx Posted October 6, 2009 Posted October 6, 2009 (edited) Did you come up with that XML format? I'm not liking it. Tag names are meant to be more generalized. A proper "database" format: expandcollapse popup<?xml version="1.0" encoding="utf-8"?> <MOVIES> <Movie Name="Drama1" Length="120" Country="USA" Genre="Drama"> <Medium> <Type>ALL</Type> </Medium> <Rating> <Mark>G</Mark> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>SE1</Branch> <Branch>NE2</Branch> </Store> <Available>YES</Available> </Movie> <Movie Name="Drama2" Length="90" Country="UK" Genre="Drama"> <Medium> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>NR</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>NO</Available> </Movie> <Movie Name="Comedy1" Length="160" Country="USA" Genre="Comedy"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>R</Mark> <Mark>NC17</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> <Movie Name="Comedy2" Length="80" Country="France" Genre="Comedy"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> </Medium> <Rating> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>NW1</Branch> <Branch>NE3</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> <Movie Name="Action1" Length="100" Country="USA" Genre="Action"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> </Medium> <Rating> <Mark>R</Mark> <Mark>NC17</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>NE3</Branch> </Store> <Available>NO</Available> </Movie> <Movie Name="Action2" Length="120" Country="Australia" Genre="Action"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>NW1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> </MOVIES> If genre is the grouping factor then you build it like this: expandcollapse popup<?xml version="1.0" encoding="utf-8"?> <MOVIES> <Genre Name="Drama"> <Movie Name="Drama1" Length="120" Country="USA"> <Medium> <Type>ALL</Type> </Medium> <Rating> <Mark>G</Mark> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>SE1</Branch> <Branch>NE2</Branch> </Store> <Available>YES</Available> </Movie> <Movie Name="Drama2" Length="90" Country="UK"> <Medium> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>NR</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>NO</Available> </Movie> </Genre> <Genre Name="Comedy"> <Movie Name="Comedy1" Length="160" Country="USA"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>R</Mark> <Mark>NC17</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> <Movie Name="Comedy2" Length="80" Country="France"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> </Medium> <Rating> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>NW1</Branch> <Branch>NE3</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> </Genre> <Genre Name="Action"> <Movie Name="Action1" Length="100" Country="USA"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> </Medium> <Rating> <Mark>R</Mark> <Mark>NC17</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>NE3</Branch> </Store> <Available>NO</Available> </Movie> <Movie Name="Action2" Length="120" Country="Australia"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>NW1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> </Genre> </MOVIES> Edited October 6, 2009 by weaponx
ayr Posted October 6, 2009 Posted October 6, 2009 weaponx, I based this example on several XMLs I've been working with for a while. Your formatting looks better though. Any ideas how I can find my way around it? thanks, ayr Did you come up with that XML format? I'm not liking it. Tag names are meant to be more generalized. A proper "database" format: expandcollapse popup<?xml version="1.0" encoding="utf-8"?> <MOVIES> <Movie Name="Drama1" Length="120" Country="USA" Genre="Drama"> <Medium> <Type>ALL</Type> </Medium> <Rating> <Mark>G</Mark> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>SE1</Branch> <Branch>NE2</Branch> </Store> <Available>YES</Available> </Movie> <Movie Name="Drama2" Length="90" Country="UK" Genre="Drama"> <Medium> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>NR</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>NO</Available> </Movie> <Movie Name="Comedy1" Length="160" Country="USA" Genre="Comedy"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>R</Mark> <Mark>NC17</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> <Movie Name="Comedy2" Length="80" Country="France" Genre="Comedy"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> </Medium> <Rating> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>NW1</Branch> <Branch>NE3</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> <Movie Name="Action1" Length="100" Country="USA" Genre="Action"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> </Medium> <Rating> <Mark>R</Mark> <Mark>NC17</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>NE3</Branch> </Store> <Available>NO</Available> </Movie> <Movie Name="Action2" Length="120" Country="Australia" Genre="Action"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>NW1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> </MOVIES> If genre is the grouping factor then you build it like this: expandcollapse popup<?xml version="1.0" encoding="utf-8"?> <MOVIES> <Genre Name="Drama"> <Movie Name="Drama1" Length="120" Country="USA"> <Medium> <Type>ALL</Type> </Medium> <Rating> <Mark>G</Mark> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>SE1</Branch> <Branch>NE2</Branch> </Store> <Available>YES</Available> </Movie> <Movie Name="Drama2" Length="90" Country="UK"> <Medium> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>NR</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>NO</Available> </Movie> </Genre> <Genre Name="Comedy"> <Movie Name="Comedy1" Length="160" Country="USA"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>R</Mark> <Mark>NC17</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> <Movie Name="Comedy2" Length="80" Country="France"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> </Medium> <Rating> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>NW1</Branch> <Branch>NE3</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> </Genre> <Genre Name="Action"> <Movie Name="Action1" Length="100" Country="USA"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> </Medium> <Rating> <Mark>R</Mark> <Mark>NC17</Mark> </Rating> <Store> <Branch>NE1</Branch> <Branch>NE2</Branch> <Branch>NE3</Branch> </Store> <Available>NO</Available> </Movie> <Movie Name="Action2" Length="120" Country="Australia"> <Medium> <Type>BLUERAY</Type> <Type>DVD</Type> <Type>VHS</Type> </Medium> <Rating> <Mark>PG</Mark> <Mark>PG13</Mark> </Rating> <Store> <Branch>NW1</Branch> <Branch>NE2</Branch> <Branch>SW1</Branch> </Store> <Available>YES</Available> </Movie> </Genre> </MOVIES>
tito Posted October 8, 2009 Posted October 8, 2009 I'm using a 'wrapper function' to the xml dom 'wrapper'. It allows a 1 line code to set or update a field or attribute. But because it's coded by me and not by an expert, I think the big if/else structure isn't good. -The XML files used with this funtion need to have a Global default 'ROOT' and a default 'First Node'. Not good. -As I couldn't get CDATA to work, the string is optionallt converted using Hex, making it unreadable without reconverting? Not good. Maybe someone can push me in the right direction how to progress ? Should it be split into multiple 'internal' functions? It IS working quite well tough! Open XML with _storageOpen($storageFile, $xslFile = "XSL.xsl", $_thisRootName="DATA", $_thisRootNode="ROOT") Set data with _storageSetter($xPath, $xKey, $xVal = "", $xUpdate = False, $xHex = False) Uses _XMLGetFirstValue(...) from forum. ; read but dont set or overwrite If _storageSetter("history", "/lastupload", "NEVER", False) = "NEVER" Then ... ; read and set if not yet set, overwrite if set If _storageSetter("history", "/lastupload", "NEVER", True) = "NEVER" Then ... ; read/set an attribute _storageSetter("TestNode[@date='"&$safeDate&"']/TestChild/Test2[@attrib='"&$attrib&"']/usethischildnode", "attribname", "attribval", True) ... _storageOpen: Global $_storageRootName, $_storageRootNode Func _storageOpen($storageFile, $xslFile = "XSL.xsl", $_thisRootName="DATA", $_thisRootNode="ROOT") Global $_storageRootName = $_thisRootName Global $_storageRootNode = $_thisRootNode $result = _XMLFileOpen($storageFile) If $result <= 0 then ;logger("_storage", "Not found! => Attempting Create...", $storageFile) _XMLCreateFile($storageFile, $_storageRootName, True, True, $xslFile) $result = _XMLFileOpen($storageFile) ;Dim $Attribs, $Values _XMLCreateRootChild($_storageRootNode) ;_XMLCreateRootNodeWAttr($_storageRootNode, $Attribs, $Values) EndIf If $result <= 0 then ;logger("_storage", "Create failed!", $storageFile) Return False EndIf ;logger("_storage", "Found!", $storageFile) ;logger("_storage", "NOW VALIDATE!", "Not yet...") EndFunc _storageSetter: expandcollapse popupFunc _storageSetter($xPath, $xKey, $xVal = "", $xUpdate = False, $xHex = False) ; Set xPath for NON-ATTRIBS If StringLeft($xKey, 1) = "/" Or $xKey = "" Then $xPath &= $xKey ; loop xPath $nodeDepth = StringSplit($xPath, "/") $nodeDepthFull = "" For $iDepth = 1 To $nodeDepth[0] ; All but First are added to xPath If $iDepth > 1 Then $nodeDepthFull &= "/"&$nodeDepth[$iDepth-1] ; Create Node if not-exists If _XMLNodeExists("//"&$_storageRootNode&$nodeDepthFull&"/"&$nodeDepth[$iDepth]) > 0 Then ; node exists, continue Else ;If $xUpdate Then ; crate node $thisNodeName = StringRegExpReplace($nodeDepth[$iDepth], '\[.*\]', "") $AttribSets = StringRegExp($nodeDepth[$iDepth], '\[.*\]', 3) $AttribsCount = UBound($AttribSets) If $AttribsCount > 0 Then ; Node WITH attribs, make em ; make Attribs Array Dim $Attribs[$AttribsCount] Dim $Values[$AttribsCount] For $iAttribSet = 0 To $AttribsCount-1 $AttribSetSplit = StringSplit($AttribSets[$iAttribSet], "=") $AttribKey = StringTrimLeft($AttribSetSplit[1], 2) $AttribVal = StringTrimRight(StringTrimLeft($AttribSetSplit[2], 1), 2) $Attribs[$iAttribSet] = $AttribKey $Values[$iAttribSet] = $AttribVal Next _XMLCreateChildWAttr("//"&$_storageRootNode&$nodeDepthFull, $thisNodeName, $Attribs, $Values) Else _XMLCreateChildNode("//"&$_storageRootNode&$nodeDepthFull, $thisNodeName) EndIf ;EndIf EndIf Next If StringLeft($xKey, 1) = "/" Or $xKey = "" Then ; NON-ATTRIB update If $xUpdate Then If $xHex Then $xVal = _StringToHex($xVal) _XMLUpdateField("//"&$_storageRootNode&"/"&$xPath, $xVal) $thisValue = _XMLGetFirstValue("//"&$_storageRootNode&"/"&$xPath) If $xHex Then $thisValue = _HexToString($thisValue) $extended = 1 SetExtended($extended, $thisValue) Return $thisValue Else $thisValue = _XMLGetFirstValue("//"&$_storageRootNode&"/"&$xPath) $extended = 0 If Not $thisValue Then $extended = 1 If $xHex Then $xVal = _StringToHex($xVal) _XMLUpdateField("//"&$_storageRootNode&"/"&$xPath, $xVal) $thisValue = _XMLGetFirstValue("//"&$_storageRootNode&"/"&$xPath) EndIf If $xHex Then $thisValue = _HexToString($thisValue) SetExtended($extended, $thisValue) Return $thisValue EndIf Else ; ATTRIB update If $xUpdate Then If $xHex Then $xVal = _StringToHex($xVal) _XMLSetAttrib("//"&$_storageRootNode&"/"&$xPath, $xKey, $xVal) $thisValue = _XMLGetAttrib("//"&$_storageRootNode&"/"&$xPath, $xKey) If $xHex Then $thisValue = _HexToString($thisValue) $extended = 1 SetExtended($extended, $thisValue) Return $thisValue Else $thisValue = _XMLGetAttrib("//"&$_storageRootNode&"/"&$xPath, $xKey) $extended = 0 If Not $thisValue Then $extended = 1 If $xHex Then $xVal = _StringToHex($xVal) _XMLSetAttrib("//"&$_storageRootNode&"/"&$xPath, $xKey, $xVal) $thisValue = _XMLGetAttrib("//"&$_storageRootNode&"/"&$xPath, $xKey) EndIf If $xHex Then $thisValue = _HexToString($thisValue) SetExtended($extended, $thisValue) Return $thisValue EndIf EndIf EndFunc _XMLGetFirstValue($node): Func _XMLGetFirstValue($node) $ret_val = _XMLGetValue($node) If IsArray($ret_val) Then ;If UBound($ret_val) > 1 Then If $ret_val[0] > 0 Then Return ($ret_val[1]) Else Return SetError(1,3,0) EndIf Else Return SetError(1,3,0) EndIf EndFunc
VAG Posted October 12, 2009 Posted October 12, 2009 Hi WeaponX, I have this code which is based on your suggested method to generate XML posting with tree layout format. It works great so far on all my projects. However, recently one of my new project requires up to 6000+ no of postings. A performance issue is discovered which lead to scienificant slow down of runtime scripts. After I trace back, the root cause was due to the increment of processing time required by XML writing in each posting. I have used a few _XMLDomWrapper methods in my libray. The timing issue mainly occur when I call _XMLCreateChildWAttr and _XMLCreateRootNodeWAttr. Part of my library:expandcollapse popupFunc _TestLog_Message($s_title, $s_remarks, $s_picture) $ROOT = "tree/" ; Record posting time $result = _Date_Time_GetLocalTime() $s_tCur = _Date_Time_SystemTimeToDateTimeStr($result) ; Define <item> Attribute Names $ATTRIBS_Name = _ArrayCreate("id", "text", "im0", "im1", "im2", "child") ; Define <userdata> attributes and values $s_userdata_name = _ArrayCreate("type", "datetime", "remarks", "picture") $s_userdata_value = _ArrayCreate("message", $s_tCur ,$s_remarks, $s_picture) ; Icon image attributes for <item> posting $s_im0 = "ms0.gif" ;icon for text $s_im1 = "ms1.gif" ;icon for open node $s_im2 = "ms2.gif" ;icon for close node ; Generate id for new posting $s_xid = Number(_XMLGetAttrib("//udf", "xid")) ;read <id> count from <udf id> attribute $s_xid = StringFormat("%05s",$s_xid+1) ; Generate unique "id" attribute from last posting entry ; Processing tree path layout $s_xnode = _XMLGetAttrib("//udf", "xpath") ;Read back xnode from temp <udf xpath> attribute $s_xpath = $s_xnode & $s_xid $SPLITPATH = StringSplit($s_xpath, "/") ;[0]: numbe of elements, [1]: element[1] ; Reset element zero to zero for blank path (null counted as 1?) If $SPLITPATH[1] = "" Then $SPLITPATH[0] = 0 ;indicate no element [0]=0 EndIf ; Generate XPATH formatting for nodes For $X = 1 to $SPLITPATH[0] $SPLITPATH[$X] = StringFormat ( "item[@id='%s']", $SPLITPATH[$X] ) ;format xpath syntax for each node, @text = <item id> Next ; Not valid if path is blank If Not $SPLITPATH[0] = 0 Then ;-------------------------- ; <item> attribute and child element ;-------------------------- ; Generate folders to accomodate items path For $X = 1 to UBound($SPLITPATH) - 1 $XPATH = $ROOT & _ArrayToString($SPLITPATH, "/", 1, $X) ;_ArrayToString = combine path items level by level ; Check if path exists If NOT IsArray(_XMLGetPath ($XPATH)) Then ;_XMLGetPath = return path item into array from node in xpath If $X > 1 Then ; CHILD item $ATTRIBS_Value = _ArrayCreate($s_xid, $s_title, $s_im0, $s_im1, $s_im2, "0") _XMLCreateChildWAttr($ROOT & _ArrayToString($SPLITPATH, "/", 1, $X - 1), "item", $ATTRIBS_Name, $ATTRIBS_Value) ; node is "tree/" + xpath Else ; ROOT item $ATTRIBS_Value = _ArrayCreate($s_xid, $s_title, $s_im0, $s_im1, $s_im2, "0") _XMLCreateRootNodeWAttr("item", $ATTRIBS_Name, $ATTRIBS_Value) ;Root node is "tree/item" EndIf EndIf Next ;-------------------------- ; <userdata> element ;-------------------------- For $X = 0 to UBound($s_userdata_name) - 1 _XMLCreateChildWAttr($XPATH, "userdata", "name", $s_userdata_name[$X], $s_userdata_value[$X]) Next EndIf ; Save UDF variable back to <udf> tag _XMLSetAttrib("//udf", "xid", $s_xid) ; save <id> count back to <udf id> attribute EndFuncExample to call:#include "_CTL_TestLog.au3" $TempXML = @ScriptDir & "\example.xml" _TestLog_Initiate($TempXML) _TestLog_Folder_Open("Test Folder", "", "") For $c=1 To 3000 $begin = TimerInit() _TestLog_Message("Test is a test message", "", "") $dif = TimerDiff($begin) ToolTip("Posting Count " & $c & ", Duration: " & $dif, 400, 400, "Test Log Performance Testing", 1) Sleep(3000) Next _TestLog_Folder_Close()The entire library:_CTL_TestLog.au3Example.au3Is there anything wrong with the way I implement the code? Thanks in advance. I have attached the generated XML, I only generated 1 level tree structure. But the increase in delay on every posting can be seen in the data. You can also see the delay when you run my Example.au3Example.xml<?xml version="1.0"?> <tree id="0"><!--CTL AutoIT Test Log - Version 1.03--> <udf xpath="" xid="03001"/> <item id="00001" text="Test Folder" im0="ms0.gif" im1="ms1.gif" im2="ms2.gif" child="1" flag="0"> <userdata name="type">folder</userdata> <userdata name="datetime">08/12/2009 15:14:47</userdata> <userdata name="remarks"/> <userdata name="picture"/> <item id="00002" text="Test is a test message" im0="ms0.gif" im1="ms1.gif" im2="ms2.gif" child="0"> <userdata name="type">message</userdata> <userdata name="datetime">08/12/2009 15:14:47</userdata> <userdata name="remarks"/> <userdata name="picture"/> </item> <item id="00003" text="Test is a test message" im0="ms0.gif" im1="ms1.gif" im2="ms2.gif" child="0"> <userdata name="type">message</userdata> <userdata name="datetime">08/12/2009 15:14:50</userdata> <userdata name="remarks"/> <userdata name="picture"/> </item> <item id="00004" text="Test is a test message" im0="ms0.gif" im1="ms1.gif" im2="ms2.gif" child="0"> <userdata name="type">message</userdata> <userdata name="datetime">08/12/2009 15:14:53</userdata> <userdata name="remarks"/> <userdata name="picture"/> </item> </item> </tree>
idbirch Posted October 20, 2009 Posted October 20, 2009 I'm having trouble parsing Windows 7 event log XML files with this UDF and I'm a bit lost to be honest. All I can get out of it is the Event child node and not much else. Here's the XML: expandcollapse popup<root> <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <System> <Provider Name="Microsoft-Windows-Diagnostics-Performance" Guid="{CFC18EC0-96B1-4EBA-961B-622CAEE05B0A}" /> <EventID>100</EventID> <Version>2</Version> <Level>2</Level> <Task>4002</Task> <Opcode>34</Opcode> <Keywords>0x8000000000010000</Keywords> <TimeCreated SystemTime="2009-10-20T07:52:27.036203000Z" /> <EventRecordID>101</EventRecordID> <Correlation ActivityID="{00000000-8B28-0000-FEDE-D9C55751CA01}" /> <Execution ProcessID="1484" ThreadID="1740" /> <Channel>Microsoft-Windows-Diagnostics-Performance/Operational</Channel> <Computer>PC5685</Computer> <Security UserID="S-1-5-19" /> </System> <EventData> <Data Name="BootTsVersion">2</Data> <Data Name="BootStartTime">2009-10-20T07:34:35.687500000Z</Data> <Data Name="BootEndTime">2009-10-20T07:52:22.750290000Z</Data> <Data Name="SystemBootInstance">16</Data> <Data Name="UserBootInstance">12</Data> <Data Name="BootTime">122713</Data> <Data Name="MainPathBootTime">108413</Data> <Data Name="BootKernelInitTime">45</Data> <Data Name="BootDriverInitTime">1124</Data> <Data Name="BootDevicesInitTime">3734</Data> <Data Name="BootPrefetchInitTime">46413</Data> <Data Name="BootPrefetchBytes">392388608</Data> <Data Name="BootAutoChkTime">0</Data> <Data Name="BootSmssInitTime">12053</Data> <Data Name="BootCriticalServicesInitTime">877</Data> <Data Name="BootUserProfileProcessingTime">4283</Data> <Data Name="BootMachineProfileProcessingTime">71256</Data> <Data Name="BootExplorerInitTime">1775</Data> <Data Name="BootNumStartupApps">10</Data> <Data Name="BootPostBootTime">14300</Data> <Data Name="BootIsRebootAfterInstall">false</Data> <Data Name="BootRootCauseStepImprovementBits">4210688</Data> <Data Name="BootRootCauseGradualImprovementBits">0</Data> <Data Name="BootRootCauseStepDegradationBits">132</Data> <Data Name="BootRootCauseGradualDegradationBits">0</Data> <Data Name="BootIsDegradation">false</Data> <Data Name="BootIsStepDegradation">false</Data> <Data Name="BootIsGradualDegradation">false</Data> <Data Name="BootImprovementDelta">0</Data> <Data Name="BootDegradationDelta">0</Data> <Data Name="BootIsRootCauseIdentified">true</Data> <Data Name="OSLoaderDuration">2609</Data> <Data Name="BootPNPInitStartTimeMS">45</Data> <Data Name="BootPNPInitDuration">3798</Data> <Data Name="OtherKernelInitDuration">2242</Data> <Data Name="SystemPNPInitStartTimeMS">5533</Data> <Data Name="SystemPNPInitDuration">1060</Data> <Data Name="SessionInitStartTimeMS">7101</Data> <Data Name="Session0InitDuration">7509</Data> <Data Name="Session1InitDuration">1402</Data> <Data Name="SessionInitOtherDuration">3141</Data> <Data Name="WinLogonstartTimeMS">19154</Data> <Data Name="OtherLogonInitActivityDuration">11943</Data> <Data Name="UserLogonWaitDuration">869462</Data> </EventData> <RenderingInfo Culture="en-GB"> <Message>Windows has started up: Boot Duration : 122713ms IsDegradation : false Incident Time (UTC) : ?2009?-?10?-?20T07:34:35.687500000Z</Message> <Level>Error</Level> <Task>Boot Performance Monitoring</Task> <Opcode>Boot Information</Opcode> <Channel>Operational</Channel> <Provider>Microsoft-Windows-Diagnostics-Performance</Provider> <Keywords> <Keyword>Event Log</Keyword> </Keywords> </RenderingInfo> </Event> </root> I just want to pull all the EventData items into an array but can't figure out for the life of me how to go about this. Any pointers would be gratefully received.
idbirch Posted October 20, 2009 Posted October 20, 2009 I think I'm having the same problem to a lot of people in not being able to get past the 'xmlns=" line in my XML file I've tried the following workaround: _XMLFileOpen($XMLpath, 'xmlns="http://schemas.microsoft.com/win/2004/08/events/event"') Local $sNodes = _XMLSelectNodes('//Event/EventData') But I'm still getting nothing returned Any help?
tim292stro Posted November 5, 2009 Posted November 5, 2009 (edited) I have a problem with the most basic portion of the UDF - I can't get a file to open. (and that makes me feel like an idiot...). I've whittled this down to the absolute basics using example code from others in this thread. Basically I want to parse a weather XML file (i'm grabbing one from google for now but I want to move to NOAA later). This is the file <?xml version="1.0"?><xml_api_reply version="1"><weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" ><forecast_information><city data="Santa Clara, CA"/><postal_code data="95051"/><latitude_e6 data=""/><longitude_e6 data=""/><forecast_date data="2009-11-05"/><current_date_time data="2009-11-05 23:52:42 +0000"/><unit_system data="US"/></forecast_information><current_conditions><condition data="Mostly Cloudy"/><temp_f data="65"/><temp_c data="18"/><humidity data="Humidity: 56%"/><icon data="/ig/images/weather/mostly_cloudy.gif"/><wind_condition data="Wind: S at 14 mph"/></current_conditions><forecast_conditions><day_of_week data="Thu"/><low data="54"/><high data="70"/><icon data="/ig/images/weather/partly_cloudy.gif"/><condition data="Partly Cloudy"/></forecast_conditions><forecast_conditions><day_of_week data="Fri"/><low data="50"/><high data="66"/><icon data="/ig/images/weather/partly_cloudy.gif"/><condition data="Partly Cloudy"/></forecast_conditions><forecast_conditions><day_of_week data="Sat"/><low data="46"/><high data="67"/><icon data="/ig/images/weather/partly_cloudy.gif"/><condition data="Partly Cloudy"/></forecast_conditions><forecast_conditions><day_of_week data="Sun"/><low data="44"/><high data="68"/><icon data="/ig/images/weather/sunny.gif"/><condition data="Sunny"/></forecast_conditions></weather></xml_api_reply> I'm using this bare-minimum code to check the file: #include <Array.au3> #include <file.au3> #Include <_XMLDomWrapper.au3> _SetDebug(True) If @error Then MsgBox(4096, "File Open", "No file chosen") Else $oOXml = "" $oOXml = _XMLFileOpen ( "C:\api.xml", "", 6) EndIf If Not IsObj($oOXml) then MsgBox(0,"Error","No Xml file.") Exit EndIf Exit When I run the script, all I ever get is the "Error, No XML file" message box. I downloaded the UDF today and I've double checked the MSXML tool is installed (I have v4 and v6 SP2). Can anyone see anything blatantly wrong here? Thanks, -Tim [edit] Oh, and I tried this with the version blank - _XMLFileOpen ( "C:\api.xml" ) - the same result, just and error box.[/edit] Edited November 6, 2009 by tim292stro
PsaltyDS Posted November 8, 2009 Posted November 8, 2009 (edited) I have a problem with the most basic portion of the UDF - I can't get a file to open. (and that makes me feel like an idiot...). I've whittled this down to the absolute basics using example code from others in this thread. Basically I want to parse a weather XML file (i'm grabbing one from google for now but I want to move to NOAA later). This is the file <?xml version="1.0"?><xml_api_reply version="1"><weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" ><forecast_information><city data="Santa Clara, CA"/><postal_code data="95051"/><latitude_e6 data=""/><longitude_e6 data=""/><forecast_date data="2009-11-05"/><current_date_time data="2009-11-05 23:52:42 +0000"/><unit_system data="US"/></forecast_information><current_conditions><condition data="Mostly Cloudy"/><temp_f data="65"/><temp_c data="18"/><humidity data="Humidity: 56%"/><icon data="/ig/images/weather/mostly_cloudy.gif"/><wind_condition data="Wind: S at 14 mph"/></current_conditions><forecast_conditions><day_of_week data="Thu"/><low data="54"/><high data="70"/><icon data="/ig/images/weather/partly_cloudy.gif"/><condition data="Partly Cloudy"/></forecast_conditions><forecast_conditions><day_of_week data="Fri"/><low data="50"/><high data="66"/><icon data="/ig/images/weather/partly_cloudy.gif"/><condition data="Partly Cloudy"/></forecast_conditions><forecast_conditions><day_of_week data="Sat"/><low data="46"/><high data="67"/><icon data="/ig/images/weather/partly_cloudy.gif"/><condition data="Partly Cloudy"/></forecast_conditions><forecast_conditions><day_of_week data="Sun"/><low data="44"/><high data="68"/><icon data="/ig/images/weather/sunny.gif"/><condition data="Sunny"/></forecast_conditions></weather></xml_api_reply> I'm using this bare-minimum code to check the file: #include <Array.au3> #include <file.au3> #Include <_XMLDomWrapper.au3> _SetDebug(True) If @error Then MsgBox(4096, "File Open", "No file chosen") Else $oOXml = "" $oOXml = _XMLFileOpen ( "C:\api.xml", "", 6) EndIf If Not IsObj($oOXml) then MsgBox(0,"Error","No Xml file.") Exit EndIf Exit When I run the script, all I ever get is the "Error, No XML file" message box. I downloaded the UDF today and I've double checked the MSXML tool is installed (I have v4 and v6 SP2). Can anyone see anything blatantly wrong here? Thanks, -Tim [edit] Oh, and I tried this with the version blank - _XMLFileOpen ( "C:\api.xml" ) - the same result, just and error box.[/edit] OK, first things first: _XMLFileOpen() does not return an object. Open the UDF file and look at the header for the function. The document object goes to an internal Global called $objDoc. Second things second: Why are you testing for @error before anything has been done? Are you expecting _SetDebug() to return an @error? Edited November 8, 2009 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
tim292stro Posted November 9, 2009 Posted November 9, 2009 (edited) OK, first things first: _XMLFileOpen() does not return an object. Open the UDF file and look at the header for the function. The document object goes to an internal Global called $objDoc. Second things second: Why are you testing for @error before anything has been done? Are you expecting _SetDebug() to return an @error? Huh.... not what I expected. I guess I'm too used to built-in functions. Yes, the "$oOXml" variable returned "-1", even thought the code is also setting the error code for the function (albiet to a totaly different number!!!) I used this code: #include <Array.au3> #include <file.au3> #Include <_XMLDomWrapper.au3> _SetDebug(True) $oOXml = _XMLFileOpen ( "C:\api.xml", "", 6 ) $TempError = @error MsgBox ( 0, "Test", "Returned value: " & $oOXml & @CRLF & "Error code: " & $TempError ) Exit The value returned was "-1" but the error code was "1". I'm used to functions that set the error code they mean and return the object's handle when it's supposed to spawn an object - much like $document = FileOpen ( "c:\textfile.txt", 0 ) returns a text file's handle to the $document variable and reports success failure via the @error macro... Thanks for the lead, it looks like I'll need to totally rewrite what the original authors did to get it to work like the other AutoIt functions... -Tim Edited November 9, 2009 by tim292stro
PsaltyDS Posted November 10, 2009 Posted November 10, 2009 Huh.... not what I expected. I guess I'm too used to built-in functions. Yes, the "$oOXml" variable returned "-1", even thought the code is also setting the error code for the function (albiet to a totaly different number!!!) I used this code: #include <Array.au3> #include <file.au3> #Include <_XMLDomWrapper.au3> _SetDebug(True) $oOXml = _XMLFileOpen ( "C:\api.xml", "", 6 ) $TempError = @error MsgBox ( 0, "Test", "Returned value: " & $oOXml & @CRLF & "Error code: " & $TempError ) Exit The value returned was "-1" but the error code was "1". I'm used to functions that set the error code they mean and return the object's handle when it's supposed to spawn an object - much like $document = FileOpen ( "c:\textfile.txt", 0 ) returns a text file's handle to the $document variable and reports success failure via the @error macro... Thanks for the lead, it looks like I'll need to totally rewrite what the original authors did to get it to work like the other AutoIt functions... -Tim I think this is a big part of why _XMLDOMWrapper has never been proposed for (as far as I know) or accepted as a part of the AutoIt distribution, like say IE.au3 or Excel.au3. It represents a LOT of good work, but would need some rewrite to be a standard UDF. The people who use it and eltorro know that and maybe there will be a push for it soon. Not having standardized XML functions in AutoIt is like not having the INI or Reg functions, it makes one of the most common operations unnecessarily difficult. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
bgjensen Posted November 21, 2009 Posted November 21, 2009 (edited) I need to change a value in a XML file. The structure looks like this: <options> <opt1> <opt name="a" type="b"> <time>1</time> </opt> </opt1> </options> I first need to read the value in <time> to a variable, and then change it to 2 in the XML file, but i can't get it to work, can someone please help me? Edited November 21, 2009 by bgjensen
PsaltyDS Posted November 25, 2009 Posted November 25, 2009 I need to change a value in a XML file.The structure looks like this:<options> <opt1> <opt name="a" type="b"> <time>1</time> </opt> </opt1></options>I first need to read the value in <time> to a variable, and then change it to 2 in the XML file, but i can't get it to work, can someone please help me?Show what you tried. This is not enough information. Are you familiar with XPath syntax? Is there a valid XML header above that in the file? Probably "options" is not the root node, so what is? Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now