xml Dokumente auslesen

Bash, Shell, PHP, Python, Perl, CGI
moppi
Posts: 368
Joined: 2003-02-15 11:16

xml Dokumente auslesen

Post by moppi »

Hallo,

ich habe ein Problem zu dem ich eine korrekte Lösung suche.
Ich sende ich ein XML Dokument an einen Server der mir dann ebenfalls mit einem XML Dokument antwortet.

Besipiel:

Code: Select all

<ErrorCode>26</ErrorCode><ErrorDescription>IP-Address not Authorized for this Operation</ErrorDescription>
Helfen würde mir dieses Dokument in ein Array zu übergeben oder gar gleich in die Variablen, da diese immer die selben sind etwa so:

Code: Select all

$xml['ErrorDescription'] = "IP-Address not Authorized for this Operation"
Das ganze in PHP wäre schön.
Bitte nur konkrete Lösungsansetze posten! Beispielscript wäre auch nicht schlecht.

Gruß
Daniel
majortermi
Userprojekt
Userprojekt
Posts: 916
Joined: 2002-06-17 16:09

Re: xml Dokumente auslesen

Post by majortermi »

Moppi wrote:Besipiel:

Code: Select all

<ErrorCode>26</ErrorCode><ErrorDescription>IP-Address not Authorized for this Operation</ErrorDescription>
Das ist kein korrektes XML, da mehr als ein Root-Element vorhanden ist.

Verarbeiten kannst du das Dokument entweder mit SAX oder mit DOM. Was sinnvoller ist, hängt davon ab, was du machen willst, in deinem Fall ist es aber wahrscheinlich DOM.
Erst nachlesen, dann nachdenken, dann nachfragen... :)
Warum man sich an diese Reihenfolge halten sollte...
moppi
Posts: 368
Joined: 2003-02-15 11:16

Re: xml Dokumente auslesen

Post by moppi »

des root hatte ich weggelassen das tut aber auch nichts zur sache an sich.
ich hatte mir zu DOM schon mehreres durchgelesen nur so richtig durchgestiegen bin ich noch nicht. daher habe ich es erstmal hier versucht, ob nicht jemand schon ähnliche probleme hatte, aber verständlich war meine ausführung schon oder?
majortermi
Userprojekt
Userprojekt
Posts: 916
Joined: 2002-06-17 16:09

Re: xml Dokumente auslesen

Post by majortermi »

Also ich kann dir mal vereinfacht den Ablauf bei DOM erklären:
DOM stellt den XML-Baum als Sammlung von Objekten dar.
Du erezeugst über die entsprechende Funktion aus einem XML-File einen solchen Baum und "hangelst" dich dann durch diesen durch, indem du das jeweilige Unterelement auswählst, bis du an der Stelle angekommen bist, die du haben willst.

Hier mal ein Beispiel, damit du vielleicht die Idee verstehst (ist allerdings in Java, nicht in PHP):

Code: Select all

        private void parseCodeNode(Node codeNode) throws JXFException {
                NodeList moduleNodes = codeNode.getChildNodes();

                for (int i = 0; i < moduleNodes.getLength(); i++) {
                        if (moduleNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
                                if (moduleNodes.item(i).getNamespaceURI() == null) {
                                        throw new JXFException("Element has no namespace");
                                }
                                if (moduleNodes.item(i).getLocalName().equals("module")
                                        && moduleNodes.item(i).getNamespaceURI().equals(JXFXMLPage.JXFPageNS)) {
                                        Node moduleNode = moduleNodes.item(i);
                                        NamedNodeMap moduleAttributes = moduleNode.getAttributes();
                                        Node moduleClassNode = moduleAttributes.getNamedItem("class");
                                        Node moduleIdentifierNode = moduleAttributes.getNamedItem("id");
                                        String moduleIdentifier = moduleIdentifierNode.getNodeValue();
                                        this.addModule(moduleIdentifier, moduleClassNode.getNodeValue());
                                        NodeList paramCallNodes = moduleNode.getChildNodes();
                                        for (int j = 0; j < paramCallNodes.getLength(); j++) {
                                                if (paramCallNodes.item(j).getNodeType() == Node.ELEMENT_NODE
                                                        && paramCallNodes.item(j).getNamespaceURI() == null) {
                                                        throw new JXFException("Element has no namespace");
                                                }
                                                if (paramCallNodes.item(j).getNodeType() == Node.ELEMENT_NODE
                                                        && paramCallNodes.item(j).getLocalName().equals("param")
                                                        && paramCallNodes.item(j).getNamespaceURI().equals(
                                                                JXFXMLPage.JXFPageNS)) {
                                                        Node paramNode = paramCallNodes.item(j);
                                                        NamedNodeMap paramAttributes = paramNode.getAttributes();
                                                        String paramName =
                                                                paramAttributes.getNamedItem("name").getNodeValue();
                                                        String paramValue = "";
                                                        NodeList paramChildren = paramNode.getChildNodes();
                                                        for (int k = 0; k < paramChildren.getLength(); k++) {
                                                                if (paramChildren.item(k).getNodeType()
                                                                        == Node.CDATA_SECTION_NODE
                                                                        || paramChildren.item(k).getNodeType() == Node.TEXT_NODE) {
                                                                        paramValue += paramChildren.item(k).getNodeValue();
                                                                }
                                                        }
                                                        this.getModule(moduleIdentifier).setAttribute(
                                                                paramName,
                                                                paramValue);
                                                }
                                                if (paramCallNodes.item(j).getNodeType() == Node.ELEMENT_NODE
                                                        && paramCallNodes.item(j).getLocalName().equals("call")
                                                        && paramCallNodes.item(j).getNamespaceURI().equals(
                                                                JXFXMLPage.JXFPageNS)) {
                                                        Node callNode = paramCallNodes.item(j);
                                                        NamedNodeMap callAttributes = callNode.getAttributes();
                                                        String callId = callAttributes.getNamedItem("id").getNodeValue();
                                                        String callFunction =
                                                                callAttributes.getNamedItem("function").getNodeValue();
                                                        Hashtable callParams = new Hashtable();
                                                        NodeList callParamNodes = callNode.getChildNodes();
                                                        for (int k = 0; k < callParamNodes.getLength(); k++) {
                                                                if (callParamNodes.item(k).getNodeType() == Node.ELEMENT_NODE
                                                                        && callParamNodes.item(k).getNamespaceURI() == null) {
                                                                        throw new JXFException("Element has no namespace");
                                                                }
                                                                if (callParamNodes.item(k).getNodeType() == Node.ELEMENT_NODE
                                                                        && callParamNodes.item(k).getLocalName().equals("param")
                                                                        && callParamNodes.item(k).getNamespaceURI().equals(
                                                                                JXFXMLPage.JXFPageNS)) {
                                                                        Node paramNode = callParamNodes.item(k);
                                                                        NamedNodeMap paramAttributes = paramNode.getAttributes();
                                                                        String paramName =
                                                                                paramAttributes.getNamedItem("name").getNodeValue();
                                                                        String paramValue = "";
                                                                        NodeList paramChildren = paramNode.getChildNodes();
                                                                        for (int l = 0; l < paramChildren.getLength(); l++) {
                                                                                if (paramChildren.item(l).getNodeType()
                                                                                        == Node.CDATA_SECTION_NODE
                                                                                        || paramChildren.item(l).getNodeType() == Node.TEXT_NODE) {
                                                                                        paramValue += paramChildren.item(l).getNodeValue();
                                                                                }
                                                                        }
                                                                        callParams.put(paramName, paramValue);
                                                                }
                                                        }
                                                        JXFFunctionCall call =
                                                                new JXFFunctionCall(callFunction, callParams, callId);
                                                        this.getModule(moduleIdentifier).addCall(call);
                                                }
                                        }
                                }
                        }
                }
        }
Alles was dort mit "JXF" steht, hat nichts mit DOM zu tun, sondern ist nur für das Projekt, aus dem der Code stammt, spezifisch.
Erst nachlesen, dann nachdenken, dann nachfragen... :)
Warum man sich an diese Reihenfolge halten sollte...
moppi
Posts: 368
Joined: 2003-02-15 11:16

Re: xml Dokumente auslesen

Post by moppi »

werde es mal formatieren und dann mal versuchen zu übersetzen.
vielen dank dir erstmal.
burn
Posts: 14
Joined: 2003-02-05 22:34
Location: Hannover

Re: xml Dokumente auslesen

Post by burn »

Ich habe das ganze über die....tada, XML Funktionen von PHP gemacht: http://www.php.net/manual/en/ref.xml.php . Auf der Seite gibt es auch gleich ein paar gute Beispiele.

Das ganze scheint mir weitaus weniger kompliziert als DOM, hat aber auch seine Grenzen. Das XML Dokument wird nicht als Baum eingelesen und kann daher nicht manipuliert werden. Um die einzelnen Ebenen des Baumes muss man sich selber kümmern, man kann im Prinzip nur Handler- Funktionen für <Starttags>, Daten und </Endtags> festlegen.
Zum einfachen Auslesen von ein paar Variablen sollte es aber allemal reichen.
majortermi
Userprojekt
Userprojekt
Posts: 916
Joined: 2002-06-17 16:09

Re: xml Dokumente auslesen

Post by majortermi »

Burn wrote:Ich habe das ganze über die....tada, XML Funktionen von PHP gemacht: http://www.php.net/manual/en/ref.xml.php . Auf der Seite gibt es auch gleich ein paar gute Beispiele.

Das ganze scheint mir weitaus weniger kompliziert als DOM, hat aber auch seine Grenzen.
Naja, wie ich gesagt habe, es kommt auf den Verwendungszweck an. Gerade wenn du komplexe Baumstrukturen hast (auch wenn du sie nicht ändern willst), hat SAX (also die von dir verwendete Methode) den Nachteil, dass du dir über Variablen merken musst, auf welcher Ebene du gerade bist. Das kann ganz schön Nerven kosten (ich spreche da aus Erfahrung).
Bei DOM ist der größte Nachteil, dass es nicht für große Dokumente geeignet ist (okay, bei PHP wird man das auf Grund der Struktur nicht merken, da wird auch SAX bei großen Dokumenten schlapp machen). In Java kann man mit SAX auch problemlos mehrere MB oder zig MB große Dokumente verarbeiten, weil eben nicht die komplette Baumstruktur im RAM gehalten werden muss.

Hier übrigens noch ein Beispiel für DOM mit PHP. Ich habe es gerade erst heute Abend geschrieben. Es wird ein RDF-Newsfeed-File ausgelesen:

Code: Select all

$content = implode('', file("extern/newsticker.rdf"));
$document = domxml_open_mem($content);
$root = $document->document_element();
$items = $root->get_elements_by_tagname("item");
foreach ($items as $item)
{
 $title_node = $item->get_elements_by_tagname("title");
 $title = $title_node[0]->get_content();
 $link_node = $item->get_elements_by_tagname("link");
 $link = $link_node[0]->get_content();
 echo "<a href="$link">".htmlspecialchars($title)."</a><br/>";
Die gleiche Sache wäre mit SAX wohl um einiges aufwendiger gewesen (in meinem Fall gingen zwei Stunden drauf, um zu merken, dass das File zwar als Encoding ISO-8859-1 angab, aber in Wahrheit Windows-1252 benutzte. Ich werde morgen mal eine Mail an den zuständigen Webmaster schicken, dass es nicht besonders nett ist, einen anderen Zeichensatz zu benutzen, als anzugeben. Ich habe nämlich 1,5 Stunden nach einem Fehler in meinem Skript gesucht (da es da auch einiges an Zeichensatz-Umwandlungen gibt, weil im Kern UTF-8 benutzt wird).
Erst nachlesen, dann nachdenken, dann nachfragen... :)
Warum man sich an diese Reihenfolge halten sollte...
moppi
Posts: 368
Joined: 2003-02-15 11:16

Re: xml Dokumente auslesen

Post by moppi »

temi kann es sein das du ein paar bytes vergessen hast zu publizieren?
majortermi
Userprojekt
Userprojekt
Posts: 916
Joined: 2002-06-17 16:09

Re: xml Dokumente auslesen

Post by majortermi »

Hm, stimmt, die "}" schließende Klammer, ist beim Kopieren irgendwie verloren gegangen. Ansonsten sollte das Beispiel aber vollständig sein.
Erst nachlesen, dann nachdenken, dann nachfragen... :)
Warum man sich an diese Reihenfolge halten sollte...
moppi
Posts: 368
Joined: 2003-02-15 11:16

Re: xml Dokumente auslesen

Post by moppi »

vielen Dank allen Helfenden.

Ich habe eine Lösung gefunden. Die XML Funktionen von PHP reichen völlig aus für meinen Zweck.

Danke
Daniel