xml problem beim auslesen

  • Hey,

    ich versuch gerade eine XML-Datei auszulesen. Ansich kein Problem bei Abschnitten ohne Attribute. Kommen Attribute ins Spiel scheitere ich -.-

    Derzeit sieht meine test.xml so aus:

    XML
    <?xml version="1.0" encoding="UTF-8"?>
    
    
    <contacts>
        <contactData errors="TESTWERT1" failures="TESTWERT2" test="TESTWERT3">
        </contactData>
    	<contactData errors1="TESTWERT1" failures1="TESTWERT2" test1="TESTWERT3">
        </contactData>
    </contacts>

    Mit dem folgenden Skript versuche ich die Attribute auszulesen. Als Array klappt es. Aber als normale Consolen- oder MsgBox Ausgabe liest er immer nur einen Wert:

    [autoit]

    #include "_XMLDomWrapper.au3"
    #include <array.au3>

    [/autoit][autoit][/autoit][autoit]

    _SetDebug (True);show debug messages via console write
    $sXmlFile = "test.xml"
    ;$sXmlFile = FileOpenDialog("", @ScriptDir, "XML (*.xml)", 1)
    ;ConsoleWrite($sXmlFile&@lf)
    If @error Then
    MsgBox(4096, "File Open", "No file chosen")
    Exit
    Else
    $oOXml = ""
    $oOXml = _XMLFileOpen ($sXmlFile)
    EndIf
    ConsoleWrite("Debug: $iRET = " & $sXmlFile & @LF)
    Dim $aAttrName[1], $aAttrValue[1], $node
    $retcnt1 = _XMLGetAllAttribNodeCount ('//contacts/contactData', "")
    ConsoleWrite("Nodes: " & $retcnt1& @LF)
    For $j = 0 To $retcnt1 - 1
    $retval = _XMLGetAllAttribIndex ("//contacts/contactData", $aAttrName, $aAttrValue, "", $j)
    ConsoleWrite("Wert:" & $aAttrName[2] & @LF)
    ConsoleWrite("Wert:" & $aAttrValue[2] & @LF)
    _ArrayDisplay($aAttrName, "Attrib Names")
    _ArrayDisplay($aAttrValue, "Attrib Values")
    Next
    Exit

    [/autoit]

    Irgend ne Ahnung warum?

    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.

    2 Mal editiert, zuletzt von mirko2002 (19. März 2012 um 00:24)

  • Hm lol,

    stimmt warum habe ich nicht auf die Variable verwiesen? *Kopf -> Tisch*

    Ok - aber selbst das klappt nicht wie es soll -.-

    Hab die XML nochmal etwas abgeändert, damit man die Werte in der Console schneller erkennt.

    XML
    <?xml version="1.0" encoding="UTF-8"?>
    
    
    <contacts>
        <contactData Name="Value1" Name2="Value2"></contactData>
        <contactData Name3="Value3" Name4="Value4"></contactData>
    </contacts>

    Source:

    [autoit]

    #include "_XMLDomWrapper.au3"
    #include <array.au3>

    [/autoit][autoit][/autoit][autoit]

    ;_SetDebug (True);show debug messages via console write
    $sXmlFile = "test.xml"
    ;$sXmlFile = FileOpenDialog("", @ScriptDir, "XML (*.xml)", 1)
    ;ConsoleWrite($sXmlFile&@lf)
    If @error Then
    MsgBox(4096, "File Open", "No file chosen")
    Exit
    Else
    $oOXml = ""
    $oOXml = _XMLFileOpen ($sXmlFile)
    EndIf
    ;ConsoleWrite("Debug: $iRET = " & $sXmlFile & @LF)
    Dim $aAttrName[1], $aAttrValue[1], $node
    $retcnt1 = _XMLGetAllAttribNodeCount ('//contacts/contactData', "")
    ;ConsoleWrite("Nodes: " & $retcnt1& @LF)
    For $j = 0 To $retcnt1 - 1
    $retval = _XMLGetAllAttribIndex ("//contacts/contactData", $aAttrName, $aAttrValue, "", $j)
    ;ConsoleWrite("Name: " & $aAttrName[$j] & @LF)
    ConsoleWrite("Value: " & $aAttrValue[$j] & @LF)
    ;_ArrayDisplay($aAttrName, "Attrib Names")
    ;_ArrayDisplay($aAttrValue, "Attrib Values")
    Next
    Exit

    [/autoit]

    Ausgabe in der Console:

    Code
    Value: Value1
    Value: Value4

    Warum gibt er nur den ersten und den vierten Wert wieder... ich raff es nicht!

    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.

  • Auszug aus der _XMLDOMWrapper.au3

    Spoiler anzeigen
    [autoit]

    ;===============================================================================
    ; Function Name: _XMLGetAllAttribIndex
    ; Description: Get all XML Field(s) attributes based on Xpathn and specific index.
    ; Parameters: $sXpath xml tree path from root node (root/child/child..)
    ; $aNames the array to return the attrib names
    ; $aValue the array to return the attrib values
    ; [$sQuery] DOM compliant query string (not really necessary as it becomes
    ; [$iNode] node index.
    ;part of the path
    ; Syntax: _XMLGetAllAttribIndex($path,$aNames,$aValues,[$sQuery="",$iNode=0]])
    ; Author(s): Stephen Podhajecki <[email='gehossafats@netmdc.com'][/email]>
    ; Returns: array of attrib node names, array of attrib values
    ; on error set error to 1 and returns -1
    ;===============================================================================
    Func _XMLGetAllAttribIndex($strXPath, ByRef $aName, ByRef $aValue, $strQry = "", $NodeIndex = 0)
    Local $objNodeList, $objQueryNodes, $objNode, $arrResponse[2][1], $i, $i1

    [/autoit] [autoit][/autoit] [autoit]

    ; $objQueryNodes = $objDoc.documentElement.selectNodes ($strXPath & $strQry)
    $objQueryNodes = $objDoc.selectNodes ($strXPath & $strQry)
    While @error = 0 And $objQueryNodes.length > 0
    $objNodeList = $objQueryNodes.item ($NodeIndex).attributes
    _DebugWrite("GetAllAttribIndex " & $objNodeList.length)
    ReDim $arrResponse[2][$objNodeList.length + 1]
    ReDim $aName[$objNodeList.length]
    ReDim $aValue[$objNodeList.length]
    For $i = 0 To $objNodeList.length - 1
    $arrResponse[0][$i] = $objNodeList.item ($i).nodeName
    $arrResponse[1][$i] = $objNodeList.item ($i).Value
    $aName[$i] = $objNodeList.item ($i).nodeName
    $aValue[$i] = $objNodeList.item ($i).Value
    Next
    Return $arrResponse
    WEnd
    ; _XMLError( "Error retrieving attributes for: " & $strXPath & @CRLF & $oMyError.windescription & @CRLF & $oMyError.scriptline)
    _XMLError( "Error retrieving attributes for: " & $strXPath & @CRLF)
    SetError(1)
    Return -1
    ; EndIf
    EndFunc ;==>_XMLGetAllAttribIndex

    [/autoit]
    Spoiler anzeigen
    [autoit]

    ;===============================================================================
    ; Function Name: _XMLGetAllAttribNodeCount
    ; Description: Get Node Count based on XPath input from root node.
    ; Parameters: $path xml tree path from root node (root/child/child..)
    ; [$query] DOM compliant query string (not really necessary as it becomes
    ;part of the path
    ; Syntax: _XMLGetAllAttribNodeCount($path,$query)
    ; Author(s): Stephen Podhajecki <[email='gehossafats@netmdc.com'][/email]> & DickB
    ; Returns: Number of Nodes found
    ; on error set error to 1 and returns -1
    ;===============================================================================
    Func _XMLGetAllAttribNodeCount($strXPath, $strQry = "")
    Local $objNodeList, $objQueryNodes, $objNode, $arrResponse[2][1], $i, $i1

    [/autoit] [autoit][/autoit] [autoit]

    $objQueryNodes = $objDoc.documentElement.selectNodes ($strXPath & $strQry)
    If @error = 0 And $objQueryNodes.length > 0 Then
    Return $objQueryNodes.length
    EndIf
    ; _XMLError( "Error retrieving attributes for: " & $strXPath & @CRLF & $oMyError.windescription & @CRLF & $oMyError.scriptline)
    _XMLError( "Error retrieving attributes for: " & $strXPath & @CRLF)
    SetError(1)
    Return -1
    ; EndIf
    EndFunc ;==>_XMLGetAllAttribNodeCount

    [/autoit]

    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.

  • Ich habe den Code mal etwas ausgedünstet, die fehlenden Teile müsstest du dann entsprechend wieder einbauen, aber für die Übersicht ist es einfach besser.
    So funktioniert es bei mir:

    Spoiler anzeigen
    [autoit]


    #include <array.au3>
    #include "_XMLDomWrapper.au3"

    [/autoit] [autoit][/autoit] [autoit]

    $sXmlFile = "C:\test.xml"
    $oOXml = ""
    $oOXml = _XMLFileOpen($sXmlFile)
    $retcnt1 = _XMLGetAllAttribNodeCount('//contacts/contactData', "")
    Dim $aAttrName[1], $aAttrValue[1]
    For $j = 0 To $retcnt1 - 1
    $retval = _XMLGetAllAttribIndex("//contacts/contactData", $aAttrName, $aAttrValue, "", $j)
    For $i = 0 To $retcnt1
    ConsoleWrite($i & ": " & $aAttrName[$i] & " | " & $aAttrValue[$i] & @CRLF)
    Next
    Next
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func _XMLGetAllAttribNodeCount($strXPath, $strQry = "")
    Local $objNodeList, $objQueryNodes, $objNode, $arrResponse[2][1], $i, $i1

    [/autoit] [autoit][/autoit] [autoit]

    $objQueryNodes = $objDoc.documentElement.selectNodes($strXPath & $strQry)
    If @error = 0 And $objQueryNodes.length > 0 Then
    Return $objQueryNodes.length
    EndIf
    ; _XMLError( "Error retrieving attributes for: " & $strXPath & @CRLF & $oMyError.windescription & @CRLF & $oMyError.scriptline)
    _XMLError("Error retrieving attributes for: " & $strXPath & @CRLF)
    SetError(1)
    Return -1
    ; EndIf
    EndFunc ;==>_XMLGetAllAttribNodeCount

    [/autoit]
  • Ok ich muss hier doch leider nochmal nachhaken - nach weiter "Umarbeitung" funktionierts doch nicht wie gehofft :(

    Das auslesen in die Console erfolgt korrekt - er kann aus einer Zeile mehrere Attribute auslesen. Nun möchte ich diese Attribute jedoch in einer(!) Zeile wieder schreiben und da haperts. Ich hoffe ich kanns einigermassen erklären - fällt mir grad nur sehr schwer ;)

    Wenn man den Code sieht wirds man evtl verstehen:

    Spoiler anzeigen
    [autoit]


    Func _LINKLISTE_BUTTON()
    $XML = @ScriptDir & "\links.xml"
    $XMLopen = _XMLFileOpen ($XML)
    Dim $aAttrName[1], $aAttrValue[1]
    $XMLcount = _XMLGetAllAttribNodeCount ('//links/linkData', "")
    FileWrite($newfile_links,"<?xml version=""1.0"" encoding=""utf-8""?>" & @CRLF & "<links>" & @CRLF)
    For $j = 0 To $XMLcount - 1
    _XMLGetAllAttribIndex("//links/linkData", $aAttrName, $aAttrValue, "", $j)
    For $i = 0 To $XMLcount - 1
    ConsoleWrite($i & ": " & $aAttrName[$i] & "=" & $aAttrValue[$i] & @CRLF)
    FileWrite($newfile_links, @TAB & '<linkData link="' & $aAttrValue[$i] & '" alternate="' & $aAttrValue[$i] & '">' & '</linkData>'& @CRLF)
    Next
    Next
    $read_input_link1 = GUICtrlRead($input_link1)
    $read_input_link2 = GUICtrlRead($input_link2)
    FileWrite($newfile_links, @TAB & '<linkData link="' & $read_input_link1 & '" alternate="' & $read_input_link2 & '">' & '</linkData>'& @CRLF)
    FileWrite($newfile_links,"</links>" & @CRLF)
    MsgBox(64,"Erfolg","XML Datei erfolgreich erstellt.")
    FileDelete("links.xml")
    FileMove("links_new.xml", "links.xml")
    EndFunc ;; _LINKLISTE_BUTTON

    [/autoit]

    In die Konsole schreibt er korrekt die Attribute rein. In die XML Datei allerdings schreibt er jeweils 2 mal hintereinander diesselben Attribute. In der nächsten Zeile schreibt er dann das nächste Attribut - dann natürlich auch 2 mal.
    Ist echt blöd zu erklären, ich hoffe man versteht was ich meine...

    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.