XML Dateien auslesen und erzeugen

  • Hallo
    Ich habe mal wieder ein Problem :)

    Ich habe eine XML Liste inder Daten nach folgenden Schema gespeichert werden:
    <Network Name="Name" ID="XYZ" Status="status" />

    und zwar meistens mehrere Einträge hintereinander...

    Ich möchte jetzt die einzelnen Zeilen auswerten,
    Also zuerst Network Name, ID und Status einlesen...

    Prüfen welchen Status die Zeile hat um dann in eine neue XML Datei zuerzeugen,
    in die unteranderem der Name geschrieben wird...

    Also da das ganze ja eigentlich nur ne bessere txt datei ist,
    dachte ich da an zuerst an fileopen und readfile
    Jetzt hätte ich die komplette Datei eingelesen,
    aber wie unterscheide ich jetzt die unterschiedlichen Einträge...
    In Java würde man ja einen Buffered Stream Reader verwenden,
    gibt es so was auch in AutoIT?
    Oder etwas ähnliches?

    Das schreiben ist dann wieder kein Problem:
    wäre ja einfach:
    FileWrite ("C:\folder\test.xml", "Hallo Netzwerk:"&$network)

    Geht das kann ich mit filewrite auch XML Dateien schreiben?

    Danke für eure Hilfe
    Alex

  • Ja Stringbetween hab ich auch gefunden würde ja dann wie im Tutorial aussehen:

    [autoit]

    #include <string.au3> ; <-- Wichtig!

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

    $string = "<html><body> Hello world! </body> </html>"
    $abda = "<html><body>"
    $bisda = " </body> </html>"

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

    $between = _StringBetween($string, $abda, $bisda)

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

    Problem dabei ist aber dass ich ja mehrere gleiche Einträge habe....
    und noch Problematischer die stehen alle nur in einer Zeile und sind durch <"Dummes Beispiel!"/>

    Das wiederholt sich dann ja wieder...

    Das heißt das Skript würde ja nur den ersten part einlesen und dann Feierabend machen...
    Oder?

    Also entweder die einzelnen Teile und dann mit Stringbetween

    oder

    alles komplett und dann iwie auseinander nehmen...

  • Wenn alle Einträge so aufgebaut sind wie dein Beispiel oben dann wird Dieser RegEx die Informationen für dich ermitteln.

    [autoit]

    $sString = '<Network Name="Name" ID="XYZ" Status="status" />'
    $aReturn = StringRegExp($sString,'<Network\sName="(.+)"\sID="(.+)"\sStatus="(.+)"\s\/>',3)
    _ArrayDisplay($aReturn)

    [/autoit]
  • Es geht net und ich finde den Fehler nicht :(

    [autoit]

    #include <String.au3>

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

    ; Script Start - Add your code below here
    $xmlPath = "C:\AutoAccept\XML\"
    $pattern = '<Network\sName="(.+)"\sID="(.+)"\sStatus="(.+)"\s\/>'
    $startNetwork="Network Name="""
    $endNetwork=""" ID="
    $startStatus="Status="""
    $endStatus=""" />"

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

    While 1
    _searchForInvitaitons($pattern)
    Sleep(1200)
    WEnd
    Exit

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

    Func _joinFS()
    Run("C:\Program Files\SYNCING.NET Technologies\SYNCING.NET\bin\SyncService.exe /script;"""&$xmlPath&"join_fsnetwork.xml""")
    Sleep(30000)
    ;Überprüfen ob Netzwerk erfolgreich erstellt wurde
    EndFunc

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

    Func _searchForInvitaitons($pattern)
    Run("C:\Program Files\SYNCING.NET Technologies\SYNCING.NET\bin\SyncService.exe /script;""C:\AutoAccept\XML\list_networks_fs.xml""")
    While FileExists("C:\sanitytests\XML\list_networks_fs.xml")=0
    ;waiting for creating Networklist
    WEnd
    $file=FileOpen("c:\sanitytests\networklists\NetworkList_file sharing.xml",0)
    $readfile = FileRead($file)
    If $readfile <> 0 Then
    $array = StringRegExp ($readfile, $pattern, 3)
    For $i = 0 To UBound($array,1)
    $networkName = _StringBetween($array[$i],$startNetwork,$endNetwork)
    $status = _StringBetween($array[$i],$startStatus,$endStatus)
    If $status = "Invited" Then
    _createXMLFile($networkName)
    _joinFS()
    EndIf
    Next
    EndIf
    EndFunc

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

    Func _createXMLFile($networkName)
    FileDelete($xmlPath & "join_fsnetwork.xml");file delete?
    While FileExists($xmlPath & "join_fsnetwork.xml") = 1

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

    WEnd
    $file=FileOpen($xmlPath & "join_fsnetwork.xml")
    FileWrite($file,"<?xml version=""1.0"" encoding=""utf-8""?><batch_commands><join_fsnetwork><definition name=""" & $networkName & """ path=""C:\AutoAccept\""/></join_fsnetwork></batch_commands>")
    FileClose($file)
    EndFunc

    [/autoit]
  • Hey
    Arbeite am besten mit

    [autoit]

    StringRegExp()

    [/autoit]


    Um diesen Befehl kennen zu lernen, würde ich dir ein Tutorial empfehlen (google einfach mal)
    MfG AntiSpeed

    Nur keine Hektik - das Leben ist stressig genug

  • ähm...
    Heißt das ich habe es falsch verwendet?

    Wenn ja was? Ich komm einfach net drauf?
    Oder verstehe ich den Befehl total falsch?

  • Die _StrinBetween() in der For-Schleife sind überflüssig. Regexp gibt dir doch bereits die benötigten Informationen.
    Ändere den Pattern mal um:

    [autoit]

    '<Network\sName="(.+?)"\sID="(.+?)"\sStatus="(.+?)"\s\/>'

    [/autoit]


    Damit findet er dann auch mehrere Netzwerke in einer Datei. Und dann schau dir das mal an:

    [autoit]

    #include <array.au3>
    $sString = '<Network Name="Name" ID="XYZ" Status="status" /><Network Name="Name2" ID="xyz" Status="status2" />'
    $array = StringRegExp($sString, '<Network\sName="(.+?)"\sID="(.+?)"\sStatus="(.+?)"\s\/>', 3)
    _ArrayDisplay($array)

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

    For $i = 0 To UBound($array) - 1 Step 3
    $networkName = $array[$i]
    $status = $array[$i + 2]
    ConsoleWrite("Netzwerk: " & $networkName & @CRLF)
    ConsoleWrite("Status: " & $status & @CRLF)
    Next

    [/autoit]
  • Hat jemand Lust zur verlinkten UDF mal ein Beispiel zu machen?
    Ich steig da nicht ganz durch :(

    Beispiel XML:

    Spoiler anzeigen

    Gesucht:
    _XML_Read_Section (inireadsection)
    _XML-Read (iniread)
    _XML_Write_Section (iniwritesection)
    _XML-Write (iniwrite)

  • Okey es geht jetzt fast :)

    Ich muss jedoch das Pattern doch noch einmal anpassen...

    Und zwar sehen die XML Files so aus:
    <?xml version="1.0" encoding="UTF-8"?><Networks><Network Name="BLA" ID="1234" Status="Invited" /></Networks>

    Der mittlere Teil wiederholt sich immer...
    aber der Anfang und das Ende kommen nur einmal vor und sollen eigentlich nur ignoriert werden,
    daher habe ich veruscht das pattern selbst zu modifizieren...
    Es sieht jetzt so aus:

    [autoit]

    $pattern = '<?xml\sversion="1.0"\sencoding="UTF-8"?>\{1}<Network\sName="(.+?)"\sID="(.+?)"\sStatus="(.+?)"\s\/>\*</Networks>\{1}'

    [/autoit]

    Geht aber net ;)

    Was geht schief?
    Grüße und dank
    Alex

  • Hallo,

    oder hiermit


    Spoiler anzeigen
    [autoit]

    ; Get the xml file
    $filename = @ScriptDir & "\Test123.xml"

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

    ; Parse the result
    $oXML = _CreateMSXMLObj()
    If Not IsObj($oXML) Then
    MsgBox(0, "_CreateMSXMLObj()", "ERROR!: Unable to create MSXML Object!!", 10)
    Exit 1
    EndIf

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

    $oXML.async = False
    $error = $oXML.Load ($filename)
    If Not $error Then
    MsgBox(0, "Load XML", "An error occurred loading " & $filename, 10)
    Exit 1
    EndIf

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

    $oXMLRoot = $oXML.documentElement
    $oAppNode = $oXML.selectSingleNode ("//customers")

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

    For $oXmlNode In $oAppNode.childNodes
    $new_name = "Hans Wurst"
    $new_age = "23"

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

    $oSubdataNode = $oXmlNode.firstchild
    ConsoleWrite("Debug: Changing Attributes." & @LF)

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

    $oSubdataNode.setAttribute ("name", $new_name)
    $oSubdataNode.setAttribute ("age", $new_age)
    Next

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

    $oXML.Save ($filename)

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

    Func _CreateMSXMLObj() ; Creates a MSXML instance depending on the version installed on the system
    $xmlObj = ObjCreate("Msxml2.DOMDocument.6.0") ; Latest available, default in Vista
    If IsObj($xmlObj) Then Return $xmlObj

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

    $xmlObj = ObjCreate("Msxml2.DOMDocument.5.0") ; Office 2003
    If IsObj($xmlObj) Then Return $xmlObj

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

    $xmlObj = ObjCreate("Msxml2.DOMDocument.4.0")
    If IsObj($xmlObj) Then Return $xmlObj

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

    $xmlObj = ObjCreate("Msxml2.DOMDocument.3.0") ; XP and w2k3 server
    If IsObj($xmlObj) Then Return $xmlObj

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

    $xmlObj = ObjCreate("Msxml2.DOMDocument.2.6") ; Win98 ME...
    If IsObj($xmlObj) Then Return $xmlObj

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

    Return 0
    EndFunc ;==>_CreateMSXMLObj

    [/autoit]

    XML Beispiel File:

    Spoiler anzeigen

    <xml>
    <customers>
    <jc>
    <subdata name="Hans Wurst" age="23" sex="male" city="cork">
    </subdata>
    </jc>
    <ts>
    <subdata name="Hans Wurst" age="23" sex="male" city="cork">
    </subdata>
    </ts>
    <bg>
    <subdata name="Hans Wurst" age="23" sex="male" city="DC">
    </subdata>
    </bg>
    </customers>
    </xml>