weaponx Posted December 9, 2008 Posted December 9, 2008 If you look at the code for _XMLFileOpen you will see that $objdoc is deleted upon parse failure, therefore trying to access it will fail. You can change the call to _XMLError below to include the line number easily. Then you just call _XMLError() after _XMLFileOpen and it will show the line number. Here is the code: If $objDoc.parseError.errorCode <> 0 Then _XMLError("Error opening specified file: " & $strXMLFile & @CRLF & $objDoc.parseError.reason) SetError($objDoc.parseError.errorCode) $objDoc = 0 Return -1 EndIf
wraithdu Posted December 12, 2008 Posted December 12, 2008 I have a little problem with the wrapper...and it might just be a bug in the component. I have the following XML file. After calline DeleteNode() / CreateNode() multiple times, blank lines start appearing in the XML file. Try the example and see all the blank lines. Any idea if there's a way to fix this? Example XML - expandcollapse popup<?xml version="1.0"?> <WMBasicEdit > <Attributes > <WMENC_QWORD Name="WM/ASFPacketCount" Value="6193" /> <WMENC_QWORD Name="WM/ASFSecurityObjectsSize" Value="0" /> <WMENC_BLOB Name="WM/StreamTypeInfo" > <![CDATA[6175647300001000800000aa00389b711c00000061010100803e0000d0070000800210000a00002200002e0080070000 ]]> </WMENC_BLOB> <WMENC_LONG Name="WM/PeakBitrate" Value="3000" /> <WMENC_STRING Name="Title" /> <WMENC_STRING Name="Author" Value="MBC" /> <WMENC_STRING Name="Copyright" Value="Motorola 2008" /> <WMENC_STRING Name="Description" /> <WMENC_STRING Name="WM/ParentalRating" /> </Attributes> <RemoveAllMarkers /> <RemoveAllScripts /> <scripts > <script Type="URL" Command="slide1.jpg" Time="5000000" /> <script Type="URL" Command="slide2.jpg" Time="464000000" /> <script Type="URL" Command="slide3.jpg" Time="995000000" /> <script Type="URL" Command="slide4.jpg" Time="2330000000" /> <script Type="URL" Command="slide5.jpg" Time="3730000000" /> <script Type="URL" Command="slide6.jpg" Time="6050000000" /> <script Type="URL" Command="slide7.jpg" Time="7095000000" /> <script Type="URL" Command="slide8.jpg" Time="8670000000" /> <script Type="URL" Command="slide9.jpg" Time="10380000000" /> <script Type="URL" Command="slide10.jpg" Time="11710000000" /> <script Type="URL" Command="slide11.jpg" Time="13395000000" /> <script Type="URL" Command="slide12.jpg" Time="14225000000" /> <script Type="URL" Command="slide13.jpg" Time="16535000000" /> <script Type="URL" Command="slide14.jpg" Time="17910000000" /> <script Type="URL" Command="trailer.html??logo" Time="19620000000" /> </Scripts> </WMBasicEdit> Test script - #include <_XMLDomWrapper.au3> _XMLFileOpen("test.txt") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*") _XMLCreateChildNode("//Scripts", "Script") _XMLDeleteNode("//Scripts/*")
wraithdu Posted December 12, 2008 Posted December 12, 2008 (edited) Well, I *kinda* fixed it by disabling AutoSave, then after manually saving the doc, re-opening it. The re-opening part is kinda lame, but it works if there's no other solution. BTW, I'm on Vista 32-bit, and AutoIt beta 3.2.13.12 OH - bugfix!! The _XMLSetAutoSave() function has the logic reversed. Oops... Edited December 12, 2008 by wraithdu
weaponx Posted December 12, 2008 Posted December 12, 2008 I mentioned this previously, I don't think I ever found a solution:#541825
wraithdu Posted December 12, 2008 Posted December 12, 2008 Reloading then manually saving the XML doc with _XMLSaveDoc() seems to remove the extra blank lines. I tried with all versions of the MSXML object, and they all have this problem. Try adding this to the end of my above test script - $objDoc = 0 _XMLFileOpen("test.txt") _XMLSaveDoc("test.txt")
scdxorange Posted December 24, 2008 Posted December 24, 2008 I have an interesting problem.XML<Settings> <Syslog AP="0" Level="0" CC="0" IP="" CN="0"/> </Settings>CODE_1Dim $name[1], $value[1] _XMLFileOpen($filename) $temp = _XMLGetAllAttrib("Settings/Syslog", $name, $value)CODE_2_XMLFileOpen($filename) $temp = _XMLGetAttrib("Settings/Syslog", "AP")CODE_1 could read attributes correctly, but CODE_2 cannot, it returns $temp = -1, and the error is "Attribute not found". What's the problem?Thanks!
weaponx Posted December 24, 2008 Posted December 24, 2008 You aren't using proper syntax in your XPATH. You need to use "//Settings/Syslog" or "/Settings/Syslog"http://www.w3.org/TR/xpathhttp://www.w3schools.com/xpath/xpath_syntax.asp
scdxorange Posted December 24, 2008 Posted December 24, 2008 How to insert a couple of nodes? For example XML1 <Settings> <Syslog AP="0" Level="0" CC="0" IP="" CN="0"/> </Settings> XML2 <SubSettings> <DebugLog JD="3" CCN="3" EC="3" MC="3" CC="3"/> <LeaveRegistry Enabled="0" /> </SubSettings> How to insert XML2 to the blank field of XML1? Thanks!
weaponx Posted December 24, 2008 Posted December 24, 2008 Dim $aKeys[1] = ["Enabled"], $aValues[1] = ["0"] _XMLCreateChildWAttr("//SubSettings", "LeaveRegistry",$aKeys,$aValues)
scdxorange Posted December 26, 2008 Posted December 26, 2008 (edited) Sorry maybe I didn't explain it clearly. The original XML is: <Settings> <Syslog AP="0" Level="0" CC="0" IP="" CN="0"/> </Settings> The XML to insert: <SubSettings> <DebugLog JD="3" CCN="3" EC="3" MC="3" CC="3"/> <LeaveRegistry Enabled="0" /> </SubSettings> After insert, it should be: <Settings> <Syslog AP="0" Level="0" CC="0" IP="" CN="0"/> <SubSettings> <DebugLog JD="3" CCN="3" EC="3" MC="3" CC="3"/> <LeaveRegistry Enabled="0" /> </SubSettings> </Settings> I don't want to create those nodes one by one. Is there any simple method to insert an existing XML? Thanks! Edited December 26, 2008 by scdxorange
weaponx Posted December 26, 2008 Posted December 26, 2008 This is the only way it can be done reliably. #include "_XMLDomWrapper.au3" $sXMLFile = "test.xml" $result = _XMLFileOpen($sXMLFile) If $result = 0 Then Exit If NOT _XMLNodeExists("//Settings/SubSettings") Then _XMLCreateChildNode("//Settings","SubSettings") EndIf Dim $aKeys[5] = ["JD", "CCN", "EC", "MC", "CC"], $aValues[5] = ["3", "3", "3", "3", "3"] _XMLCreateChildWAttr("//Settings/SubSettings", "DebugLog",$aKeys,$aValues) Dim $aKeys[1] = ["Enabled"], $aValues[1] = ["0"] _XMLCreateChildWAttr("//Settings/SubSettings", "LeaveRegistry",$aKeys,$aValues)
Garp99HasSpoken Posted December 31, 2008 Posted December 31, 2008 Can this wrapper be used to convert fields in one XML file into the format for a different XML file? In other words, I want to convert an XML file into a new format for a different program to use. Are there examples on the site forum that I missed?
weaponx Posted December 31, 2008 Posted December 31, 2008 Can this wrapper be used to convert fields in one XML file into the format for a different XML file?In other words, I want to convert an XML file into a new format for a different program to use.Are there examples on the site forum that I missed?This is called a transformation. This UDF can transform an XML file with a given XSL file. XSL is quite difficult so I will be of little help. Maybe if you could post a small sample of the original XML and the expected result I could take a look.
Garp99HasSpoken Posted January 2, 2009 Posted January 2, 2009 Basically someone was asking about converting a movie xml file from a website into XBMC xml (which is called .nfo), like expandcollapse popup<Titles> <Title> <ID>1</ID> <WebServiceID>bd4332a4-f545-4642-8ba2-68ba4b8371cf</WebServiceID> <CollectionNumber>1</CollectionNumber> <Type>DVD</Type> <Barcode>7321970139297</Barcode> <Country>Denmark</Country> <LocalTitle>The Brave One</LocalTitle> <OriginalTitle>The Brave One</OriginalTitle> <SortTitle>Brave One, The</SortTitle> <IMDB>tt0476964</IMDB> <Description><![CDATA[Hver dag fortæller New York'er radio-værten Erica Bain (Jodie Foster) levende om New York i sit show; om byens finurligheder, stemninger og alle lydene. Hun tager jævnligt ud i byen og optager lydklip, der senere bliver brugt i hendes programmer. Hun elsker virkelig byen, og det kan man mærke. ]]></Description> <ExtraFeatures NotPresent="True"><![CDATA[]]></ExtraFeatures> <ParentalRating Adult="False"> <Value>6</Value> <Description> </Description> </ParentalRating> <Covers> <Front>C:\Documents and Settings\All Users\Application Data\My Movies\FileStorage\Covers\797f0ebb-a323-467d-b325-1f6c6feed116.jpg</Front> <Back>C:\Documents and Settings\All Users\Application Data\My Movies\FileStorage\Covers\63f5a41f-e833-4f3e-aec0-03966b50737b.jpg</Back> </Covers> <Genres> <Genre>Suspense/Thriller</Genre> </Genres> <Persons ActorsComplete="False"> <Person Type="1"> <Name>Naveen Andrews</Name> <Type>Actor</Type> <Role>David Kirmani</Role> </Person> <Person Type="1"> <Name>Nicky Katt</Name> <Type>Actor</Type> <Role>Detective Vitale</Role> </Person> </Persons> </Title> </Titles> to XMBC like <movie> <title></title> <originaltitle></originaltitle> // currently unused in YAMJ <rating></rating> // 0 - 10 rating, can be decimal <year></year> <outline></outline> // a short plot description <plot></plot> // a longer plot description <runtime></runtime> <thumb></thumb> // url of poster image. use URL formatting, such as http:// for internet resources or file:// for local resources <fanart></fanart> // url of fanart image. use URL formatting, such as http:// for internet resources or file:// for local resources <mpaa></mpaa> <id></id> // the IMDB id of the movie. includes the leading "tt" <genre></genre> // multiple genre records may exist, including any custom ones <director></director> <actor> // multiple actor records may exist <name></name> <role></role> </actor> </movie> Of course there are more fields in both, some unused in XBMC, some not needed from original, but that's the beginning stages of conversion.
weaponx Posted January 5, 2009 Posted January 5, 2009 (edited) Alright, here is a working transformation. Unfortunately there isn't enough information from the original XML to satisfy the expected xml.#include "_XMLDomWrapper.au3" $inFile = @ScriptDir & '\in.xml' $outFile = @ScriptDir & '\out.xml' $xsl = @ScriptDir & '\test.xsl' $result = _XMLFileOpen($inFile) If @ERROR <> 0 Then MsgBox(0,"","Error opening " & $inFile) Exit EndIf _XMLTransform($result, $xsl, $outFile)test.xsl:<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="utf-8"/> <xsl:template match="/"> <movies> <xsl:for-each select="Titles/Title"> <movie> <title><xsl:value-of select="LocalTitle"/></title> <originaltitle><xsl:value-of select="OriginalTitle"/></originaltitle> <!-- currently unused in YAMJ --> <rating></rating> <!-- 0 - 10 rating, can be decimal --> <year></year> <outline></outline> <!-- a short plot description --> <plot></plot> <!-- a longer plot description --> <runtime></runtime> <thumb></thumb> <!-- url of poster image. use URL formatting, such as http:// for internet resources or file:// for local resources --> <fanart></fanart> <!-- url of fanart image. use URL formatting, such as http:// for internet resources or file:// for local resources --> <mpaa></mpaa> <id><xsl:value-of select="IMDB"/></id> <!-- the IMDB id of the movie. includes the leading "tt" --> <genre></genre> <!-- multiple genre records may exist, including any custom ones --> <director></director> <xsl:for-each select="Persons/Person"> <actor> <!-- multiple actor records may exist --> <name><xsl:value-of select="Name"/></name> <role><xsl:value-of select="Role"/></role> </actor> </xsl:for-each> </movie> </xsl:for-each> </movies> </xsl:template> </xsl:stylesheet>Result:<?xml version="1.0" encoding="utf-8"?> <movies> <movie> <title>The Brave One</title> <originaltitle>The Brave One</originaltitle> <rating></rating> <year></year> <outline></outline> <plot></plot> <runtime></runtime> <thumb></thumb> <fanart></fanart> <mpaa></mpaa> <id>tt0476964</id> <genre></genre> <director></director> <actor> <name>Naveen Andrews</name> <role>David Kirmani</role> </actor> <actor> <name>Nicky Katt</name> <role>Detective Vitale</role> </actor> </movie> </movies> Edited January 5, 2009 by weaponx
VAG Posted January 12, 2009 Posted January 12, 2009 I am trying to create a XML test log lib for my autoit test script by using XML Dom Wrapper. I would like to made function for my test log so that whenever I call for it a new entry will be appended onto the existing xml file. The file will be saved after every posting so that I won't have a broken xml if my test fails. I don't need to go back and modify the previous posting. I will use a XSL to format it for properly reading later. I have some knowledge in XML but new to AutoIt & XML Dom Wrapper. I have tried to look thru the postings and use the example to create a simple xml structure. But then the child entries are based on index. I am not sure how to navigate it if I just wanted to append the new entry to the end of the structure. Is it possible for you to provide some help on this? My XML test log format:CODE<?xml version="1.0" ?> - <Event_Log>- <TestLog ID="0001"><Type>xxxx</Type> <Message>xxxx</Message> <Time>xxxx</Time> <Picture>xxxx</Picture> <Remarks>xxxx</Remarks> </TestLog>- <TestLog ID="0002"><Type>xxxx</Type> <Message>xxxx</Message> <Time>xxxx</Time> <Picture>xxxx</Picture> <Remarks>xxxx</Remarks> </TestLog> </Event_Log>
weaponx Posted January 12, 2009 Posted January 12, 2009 This is a basic example. It relies on at least one entry to already be in the file. You can fix that by using XMLSelectNodes to see if there is at least one TestLog entry. #include "_XMLDomWrapper.au3" $sXMLFile = "logging.xml" $root = "//Event_Log" $result = _XMLFileOpen($sXMLFile) If $result = 0 Then MsgBox(0,"","File not found") Exit EndIf ;Get last log id $result = Number(_XMLGetAttrib($root & "/TestLog[last()]", "ID")) If @ERROR Then ;ConsoleWrite("@ERROR: " & @ERROR & @CRLF) Exit Else ;ConsoleWrite($result & @CRLF) EndIf _XMLCreateRootChild ("TestLog", "") _XMLSetAttrib($root & "/TestLog[last()]", "ID", StringFormat("%04s",$result+1)) ;Increment, convert to string, pad to 4 characters _XMLCreateChildNode ($root & "/TestLog[last()]", "Type", "xxxx") _XMLCreateChildNode ($root & "/TestLog[last()]", "Message", "xxxx") _XMLCreateChildNode ($root & "TestLog[last()]", "Time", "xxxx") _XMLCreateChildNode ($root & "/TestLog[last()]", "Picture", "xxxx") _XMLCreateChildNode ($root & "/TestLog[last()]", "Remarks", "xxxx")
VAG Posted January 13, 2009 Posted January 13, 2009 Thanks for the great help Based on your example, I have created some working functions for test log posting. However, during the development, I noticed that sometime I need to create folders to contain multiple entries in order to organize them properly. I have think of a function to create sub folder similar to CreatChildNode. The function can accept "Open" & "Close" control during my postings. So that I can call for it whenever I need to group certian number of entries. However when I started the development, I have faced some difficuties on how to handle the entries' running IDs, storage of current xpath, and handling of multiple level of folders. Is it possible for you to provide me some insight on how to do it properly? I have attached my working code as a reference. CODE#Include "Date.au3" #include "_XMLDomWrapper.au3" ;=============================================================================== ;[Function Local Variable] ;_TestLog_Initiate() Dim $s_xroot ;_TestLog_Message() Dim $s_XMLFile ;=============================================================================== ;=============================================================================== ; Function Name: _TestLog_Initiate($s_Path) ; Category: Initiate, Test Log ; Description:: Create XML testlog template for logging. ; Parameter(s): [$s_XMLFile] - full path of test log file ; Requirement(s): #include <"_XMLDomWrapper.au3"> ; Return Value(s): $s_xroot contains root xpath "//Test_Log". ; $s_XMLFile contains current working XML file. ; Author(s): Peter Yeung 13 Jan 2009 ; Bugs: Overwrite existing test log file if exists ; Create root node "//Test_Log" ;=============================================================================== Func _TestLog_Initiate($s_Path) ;Create file (force overwrite existing file) $result = _XMLCreateFile($s_Path, "Test_Log", 1) Switch @error Case 0 ;"No error" Case 1 MsgBox(0,"_TestLog_Initiate()","Failed to create file") Case 2 MsgBox(0,"_TestLog_Initiate()","No object") Case 3 MsgBox(0,"_TestLog_Initiate()","File creation failed MSXML error") Case 4 MsgBox(0,"_TestLog_Initiate()","File exists") EndSwitch $s_xroot = "//Test_Log" $s_XMLFile = $s_Path EndFunc ;=============================================================================== ; Function Name: _TestLog_Message($s_Path) ; Category: Message, Test Log ; Description:: Posting message into test log. ; Parameter(s): [$s_message] - string for [Message] tag. ; [$s_remarks] - string for [Remarks] tag. ; Requirement(s): #include <_XMLDomWrapper.au3>, #Include <Date.au3> ; _Testlog_Initiate() ; Dim $s_xroot, Dim $s_XMLFile ; Return Value(s): NA ; Author(s): Peter Yeung 13 Jan 2009 ; Bugs: Create 1st node if no node is available ; Auto input DateTime in [Time] tag ; [DataPro] tag set to "Message" ;=============================================================================== Func _TestLog_Message($s_message, $s_remarks) ; Record posting time $tCur = _Date_Time_GetLocalTime() ; Open XML file $result = _XMLFileOpen($s_XMLFile) If $result = 0 Then MsgBox(0,"_TestLog_Message()","File not found") Exit EndIf ; Check if last node is available $result = _XMLSelectNodes($s_xroot & "/Log[last()]") If $result = -1 Then ; Create new child entry _XMLCreateRootChild ("Log", "") _XMLSetAttrib($s_xroot & "/Log[1]", "ID", StringFormat("%04s",1)) ;convert to string, pad to 4 characters (4 digits) _XMLCreateChildNode ($s_xroot & "/Log[last()]", "Message", $s_message) _XMLCreateChildNode ($s_xroot & "/Log[last()]", "Time", _Date_Time_SystemTimeToDateTimeStr($tCur)) _XMLCreateChildNode ($s_xroot & "/Log[last()]", "Picture", "") _XMLCreateChildNode ($s_xroot & "/Log[last()]", "Remarks", $s_remarks) _XMLCreateChildNode ($s_xroot & "/Log[last()]", "DataPro", "Message") Else ; Get last entry id $result = Number(_XMLGetAttrib($s_xroot & "/Log[last()]", "ID")) ; Append new child entry _XMLCreateRootChild ("Log", "") _XMLSetAttrib($s_xroot & "/Log[last()]", "ID", StringFormat("%04s",$result+1)) ;Increment, convert to string, pad to 4 characters (4 digits) _XMLCreateChildNode ($s_xroot & "/Log[last()]", "Message", $s_message) _XMLCreateChildNode ($s_xroot & "/Log[last()]", "Time", _Date_Time_SystemTimeToDateTimeStr($tCur)) _XMLCreateChildNode ($s_xroot & "/Log[last()]", "Picture", "") _XMLCreateChildNode ($s_xroot & "/Log[last()]", "Remarks", $s_remarks) _XMLCreateChildNode ($s_xroot & "/Log[last()]", "DataPro", "Message") EndIf EndFunc ;----------------------------------End of Code---------------------------------- ;Code example: $TempXML = @ScriptDir & "\example.xml" _TestLog_Initiate($TempXML) _TestLog_Message("Testing...", "Testing...") Sleep (5000) _TestLog_Message("Testing...2", "Testing...2")
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