Jump to content

XML DOM wrapper (COM)


eltorro
 Share

Recommended Posts

Thanks for the fast answer - but unfortunately it's not working for me ... You sayed you got a test file working with the modifications. So I think (and hope) I have something wrong/different ... So here my "specs":

I added your suggestion with the new parameter '$bValOnParse' to the UDF (1.0.3.59 - think it's the newest one?) and simplified the .xml:

<!DOCTYPE preferences>

<preferences>

<group>

<option value="foo" />

</group>

</preferences>

With

_SetDebug(true)

_XMLFileOpen("test.xml")

$var = _XMLGetAttrib("preferences/group/option", "value")

$var is -1 - The tracewindow says "Attribute value not found for: preferences/group/option" and "No qualified items found".

But without the <!DOCTYPE preferences> in the .xml I get my "foo" into $var ...

As used dll the msxml6.dll is reported, I use the actual AU3 version v3.2.4.9

Thanks for your help,

Linus

Link to comment
Share on other sites

Thanks for the fast answer - but unfortunately it's not working for me ... You sayed you got a test file working with the modifications. So I think (and hope) I have something wrong/different ... So here my "specs":

I added your suggestion with the new parameter '$bValOnParse' to the UDF (1.0.3.59 - think it's the newest one?) and simplified the .xml:

<!DOCTYPE preferences>

<preferences>

<group>

<option value="foo" />

</group>

</preferences>

With

_SetDebug(true)

_XMLFileOpen("test.xml")

$var = _XMLGetAttrib("preferences/group/option", "value")

$var is -1 - The tracewindow says "Attribute value not found for: preferences/group/option" and "No qualified items found".

But without the <!DOCTYPE preferences> in the .xml I get my "foo" into $var ...

As used dll the msxml6.dll is reported, I use the actual AU3 version v3.2.4.9

Thanks for your help,

Linus

The problem seems to be related to msxml6. msxml4 will read the attribute with or without adding the $objDoc.validateOnParse = True/False statement. I'll have to research some to find a resolution for msxml6. For the moment, you can override the msxml version with

_XMLFileOpen ("test.xml","",4)
Link to comment
Share on other sites

Ok found the magic property for msxml6 :

Add this before the $objDoc.Load()

if $DOMVERSION > 4 Then $objDoc.setProperty("ProhibitDTD", false)
Link to comment
Share on other sites

That's it, thanks a lot for your fast help. And the new parameter for the _XMLFileOpen is a good idea, will make it usable even for 'bad' .xml's. And one more time: I think this UDF should be part of the AU3-releases!!

Link to comment
Share on other sites

Here is my xml

nothing fancy just nodes with data

<?xml version="1.0" encoding="ISO-8859-1"?>
<Test_Case>
<id>Help - About ~ OK</id>
<test_title>2</test_title>
<test_duration>00:00</test_duration>
<test_type>[None Selected]</test_type>
<test_phase>[None Selected]</test_phase>
<create_date>20070412</create_date>
<create_time>16:58:18</create_time>
<update_date>20070515</update_date>
<update_time>08:44:21</update_time>
<create_user_id>CGH</create_user_id>
<update_user_id>JV</update_user_id>
<rec_test_configs></rec_test_configs>
<test_resources></test_resources>
<prerequisites></prerequisites>
<test_description><![CDATA[Click<br>cmdOk]]></test_description>
<test_result></test_result>
<notes1></notes1>
<notes2></notes2>
<external_link></external_link>
<priority>2</priority>
<requirement>3.5</requirement>
</Test_Case>
oÝ÷ Ù8^~*춫¯&®¶­s` ¢b33c¶æöFRÒõÔÄvWD6ÆDæöFW2gV÷C²õFW7Eô66RgV÷C²¢oÝ÷ Û
+Áek   ^²ÉrÚÞ¶ê籩ڮ¶²Â+ay§!^jÆéا¶®¶²¶¬yÊ'v«¯&®¶­s` ¢b33c·fÇVRÒõÔÄvWDfVÆBgV÷C²õFW7Eô66RgV÷C²¢

finds all the correct values, but puts all values in element [1]

I expect the _XMLGetField to return an array with each value an element

But, maybe i am wrong in the expected behavior

Link to comment
Share on other sites

One additon:

Seems that the new parameter is not necessary - it's also working with my example-.xml and

CODE
Func _XMLFileOpen($strXMLFile, $strNameSpc = "", $ver = -1)

...

if $DOMVERSION > 4 Then $objDoc.setProperty("ProhibitDTD", false)

$objDoc.validateOnParse = True

$objDoc.Load ($strFile)

.validateOnParse must be set - but no matter if true or false - I allways get my 'foo' (and that's all I wanted ...)

Thanks again,

Linus

Link to comment
Share on other sites

But i just noticed somthing that yiou might want to standerdize

when _XMLGetChildNodes is run, it returns an array with the array count in element[0] and then data starting in element [1]

when _XMLGetfield is run, it does not add the array count but starts putting data in element [0]

Not a huge issue, but it would be nice if the Node element and Field element relate to each other

Thanks Again

RB

Link to comment
Share on other sites

Never mind my brain had a fart

It is adding the count, but it appears to exiting the loop one element early

ie, it does not grab the last value

But i just noticed somthing that yiou might want to standerdize

when _XMLGetChildNodes is run, it returns an array with the array count in element[0] and then data starting in element [1]

when _XMLGetfield is run, it does not add the array count but starts putting data in element [0]

Not a huge issue, but it would be nice if the Node element and Field element relate to each other

Thanks Again

RB

Link to comment
Share on other sites

Fixed.

change line 291 to:

For $x = 1 to count

or download updated version.

Link to comment
Share on other sites

After many grueling, painful nights working on this I finally have a fun example of this UDF.

I created a program launching utility as part of an Anti-Spyware / Antivirus / Driver cd shown here:

Posted Image

Download here

- The menu structure is read from an xml file (more specifically config.xml in the same folder)

- The xml file is going to be generated on the fly as part of larger program i'm working on.

- The following program will generate config.xml and sort all of the items (like Explorer detail view)

The script which generates the xml is here archrivalxml.au3

And here is the XSL transformation code (Forum doesn't allow XSL attachments)

Below is the archrivalxml.au3 code which will give the result in the picture above.

Basically you call insertnode("Program name here", "Path\to\program.exe (relative to current folder)", "oscode (see below)")

Archrival Utilities will detect your OS and only show menu items matching it

OS Codes (Add together for multiple):

000 - ---

001 - NT4

002 - 95

004 - 98

008 - ME

016 - 2000

032 - XP

064 - 2003

128 - ???

255 - ALL

#include <Includes/_XMLDomWrapper.au3>
#include <Array.au3>

Dim $sFile = "config.xml"

FileDelete ( $sFile )

_XMLCreateFile ($sFile, "menu", True)
$XMLOBJECT = _XMLFileOpen ($sFile)

;Attributes for a folder item
$ATTRIBS1 = _ArrayCreate("name", "oscode")

;Attributes for a program item
$ATTRIBS2 = _ArrayCreate("name", "target", "oscode")

;Fake item 1
insertNode("Spyware/Install/Silent", _ArrayCreate("Great-Grandchild item", "PATH\TO\PROGRAM.EXE", "255"))

;Fake item 2
insertNode("Spyware/Install", _ArrayCreate("Grandchild item", "PATH\TO\PROGRAM.EXE", "255"))

;Fake item 3
insertNode("Spyware", _ArrayCreate("Child item", "PATH\TO\PROGRAM.EXE", "255"))

;Fake item 4
insertNode("", _ArrayCreate("Root item", "PATH\TO\PROGRAM.EXE", "255"))

;Fake item 5
insertNode("Antivirus", _ArrayCreate("Another child item", "PATH\TO\PROGRAM.EXE", "255"))

;Fake item 7
insertNode("Spyware/TEST", _ArrayCreate("Great-Grandchild item", "PATH\TO\PROGRAM.EXE", "255"))

;Transform if stylesheet exists
If FileExists ( "config.xsl" ) Then
    _XMLTransform ( $XMLOBJECT, "config.xsl","config.xml" )
EndIf


Func insertNode($PATH, $VALUES)
    $SPLITPATH = StringSplit($PATH, "/")
    
    ;Reset element zero to zero for blank path (null counted as 1?)
    If $SPLITPATH[1] = "" Then $SPLITPATH[0] = 0
    
    ;Maintain original path
    $ORIGINALPATH = $SPLITPATH
    
    $ROOT = "menu/"
    
    ;Generate XPATH formatting for nodes
    For $X = 1 to $SPLITPATH[0]
        $SPLITPATH[$X] = StringFormat ( "folder[@name='%s']", $SPLITPATH[$X] )
    Next
        
    ;Check if path is blank, if so create item in root
    If $SPLITPATH[0] Then
        
        ;Generate folders to accomodate items path
        For $X = 1 to $SPLITPATH[0]
            
            $XPATH = $ROOT & _ArrayToString ( $SPLITPATH, "/", 1, $X )
            
            ;Check if path exists
            If NOT IsArray ( _XMLGetPath ($XPATH) ) Then
                ;MsgBox(48,"", $XPATH & " doesn't exist")
                If $X > 1 Then
                    ;CHILD FOLDER
                    _XMLCreateChildWAttr($ROOT & _ArrayToString ( $SPLITPATH, "/", 1, $X - 1), "folder", $ATTRIBS1, _ArrayCreate($ORIGINALPATH[$X], "255"))
                Else
                    ;ROOT FOLDER
                    _XMLCreateRootNodeWAttr("folder", $ATTRIBS1, _ArrayCreate($ORIGINALPATH[$X], "255"))
                EndIf
            EndIf
        Next
        
        ;MsgBox(48,"", $XPATH)
        ;CHILD ITEM
        _XMLCreateChildWAttr($XPATH, "item", $ATTRIBS2, $VALUES)
        
    Else
        ;ROOT ITEM
        _XMLCreateRootNodeWAttr("item", $ATTRIBS2, $VALUES)
    EndIf
    
EndFunc
Edited by weaponx
Link to comment
Share on other sites

Great!, Glad to see you got the sorting figured out.

The GUI looks fantastic.

Is your whole script in AutoIt or just just the xml creation/transformation?

Edited by eltorro
Link to comment
Share on other sites

Great!, Glad to see you got the sorting figured out.

The GUI looks fantastic.

Is your whole script in AutoIt or just just the xml creation/transformation?

The menu was created in Flash and made into an exe with a program called SWF Studio which is very cool. The program is kind of expensive ($300) but it can run tons of prebuilt system commands.

Link to comment
Share on other sites

Hi,

I'm just new to XML and would like some help reading from my XML file using this wrapper. My XML is;

<tv>

<channel id="01">

<display-name>TV1</display-name>

<icon src="http://www.gbpvr.com/logo/TV1.jpeg" />

</channel>

<channel id="02">

<display-name>TV2</display-name>

<icon src="http://www.gbpvr.com/logo/TV2.jpeg" />

</channel>

</tv>

What is the function I use to put "TV1" from the above XML into a variable? Do I use _XMLGetValue?

And also, what one to put "http://www.gbpvr.com/logo/TV1.jpeg" into a variable?

Thanks.

Link to comment
Share on other sites

#Include <user/_XMLDomWrapper.au3>
#include <Array.au3>
_XMLFilSÜ[ ][ÝÝ[ ][ÝÊBÜ]ÈH^BÌÍÝWÖSÙ][YJ ÌÎNËÝö6ææVÅ´CÒgV÷C³gV÷CµÒöF7ÆÖæÖRb33²¤6öç6öÆUw&FRb33c·f"¥ô'åÕµÀ ÀÌØíÙÈ°ÅÕ½ÐìÅÕ½Ðì¤((íÉÑÕɹÌÙ±Õ(ÀÌØíÙÈô}a51ÑÑÑÉ¥ #39;/tv/channel[@id="01"]/icon',"src")
ConsoleWrite    ÌÍÝBÙØÞ
    ][ÝÚXÛÛ][ÝË   ÌÍÝB[ÈÐ^Q[
    ÌͶf"Âb33c·5FFÆSÒgV÷C²gV÷C²¤×6t&÷#cc3BÂb33c·5FFÆRÅô'&Fõ7G&ærÀÌØíYȱ1¤¤)¹Õ¹((

Link to comment
Share on other sites

Thanks, that works, but how come when I run it a "1" is also included in the first var? I would expect just "TV1"?

---------------------------

---------------------------

1

TV1

---------------------------

OK

---------------------------

Link to comment
Share on other sites

Thanks, that works, but how come when I run it a "1" is also included in the first var? I would expect just "TV1"?

---------------------------

---------------------------

1

TV1

---------------------------

OK

---------------------------

The 1 is the number of values that follows. Although not in your example, XML can have more than 1 node with the same tag name.

Link to comment
Share on other sites

hi,

i've been trying to get your xml functions to work, but as I noob I just can't get it to work...

maybe it's because the xml file i'm using is , not complex, but is different from other examples/tutorials I saw...

could someone give me a hint pls ?

the xml data i'm using is from youtube's dev api

the following request : http://www.youtube.com/api2_rest?method=yo...&per_page=5

returns the following xml file :

<?xml version="1.0" encoding="utf-8"?>

<ut_response status="ok">

<video_list>

<total>12345</total>

<video>

<author>author...</author>

<id>my youtube dev id</id>

<title>title...</title>

<length_seconds>12345</length_seconds>

<rating_avg>1.23</rating_avg>

<rating_count>12345</rating_count>

<description>description...</description>

<view_count>12345</view_count>

<upload_time>1166381229</upload_time>

<comment_count>12345</comment_count>

<tags>tag_1 tag_2 tag_3 tag_x</tags>

<url>http://www.youtube.com/?v=UNIQUE_NR_1</url>

<thumbnail_url>http://img.youtube.com/vi/UNIQUE_NR_1/2.jpg</thumbnail_url>

</video>

<video>

<author>author...</author>

<id>my youtube dev id</id>

<title>title...</title>

<length_seconds>12345</length_seconds>

<rating_avg>1.23</rating_avg>

<rating_count>12345</rating_count>

<description>description...</description>

<view_count>12345</view_count>

<upload_time>1166381229</upload_time>

<comment_count>12345</comment_count>

<tags>tag_1 tag_2 tag_3 tag_x</tags>

<url>http://www.youtube.com/?v=UNIQUE_NR_2</url>

<thumbnail_url>http://img.youtube.com/vi/UNIQUE_NR_2/2.jpg</thumbnail_url>

</video>

<video>

...

</video>

</video_list>

</ut_response>
so how would I fe put all this info in an multi-array like this :

$data[$i][title][thumbnail_url] ?

thx in advance;

chrs, tito

Link to comment
Share on other sites

The 1 is the number of values that follows. Although not in your example, XML can have more than 1 node with the same tag name.

So I would have to use some kind of regular expression to get just "TV1"? I want to add that text to a label...
Link to comment
Share on other sites

so how would I fe put all this info in an multi-array like this :

$data[$i][title][thumbnail_url] ?

thx in advance;

chrs, tito

Thing you are looking for is Hash which is not natively implemented in AutoIt. However MrRider wrote one that i use for quite a while and which works just fine (maybe a little slow but it does the job). Try it out.

http://www.autoitscript.com/forum/index.ph...611&hl=hash

My little company: Evotec (PL version: Evotec)

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...