Leeloo5E: + PHP: kleiner < und größer >

Hallo,

bei XML ist es ja so, dass es wohlgeformt sein muss. D.h. jedes geöffnete Tag muss auch geschlossen werden. Soweit eigentlich kein Problem. Allerdings stolpere ich gerade über einfach < und > im normalen Text ...

Fangen wir von vorne an: Ich baue mir mit Hilfe von DOMImplementation von PHP ein XML-Dokument in UTF-8. Damit auch jeder Inhalt der erstellten XML-Tags akzeptiert werden, muss ich sie maskieren, mittels htmlentites (sorry, ein anderer Weg ist mir grad nicht eingefallen). Kommt nämlich sonst sowas wie ein einfaches "&" wird wieder rumgejammert, also maskieren: &amp;
Bei Anwendung von saveXML() - also den generierten Baum als String speichern, werden scheinbar < und >, die im normalen Text enthalten sind, automatisch maskiert. Das sind übrigens öffnende und schließende HTML-Tags, die mittels eines Editors eingegeben wurden -> d.h. Wohlgeformtheit bleibt erhalten. Ich weiß ganz genau, ich habe sie nicht maskiert. Um sie wieder zu ordentlichen Tags zu machen, muss ich sie mit html_entity_decode wieder umwandeln. Dummerweise werden auf diesem Weg auch die einfachen größer und kleiner im Text (" 1 < 2 < 3 > 2 > 1") wieder zurück verwandelt. Beim Laden des XML-Strings in ein neues XML-Dokument mittels new DomDocument und loadXML() sagt der:

Warning: DOMDocument::loadXML(): xmlParseEntityRef: no name in Entity,

DOMDocument::loadXML(): StartTag: invalid element name in Entity

Wie krieg kann ich die wirklichen Tags erhalten, so dass html_entity_decode flach fällt, aber die einfachen Zeichen < und > maskiert, dass loadXML sie akzeptiert?

Gruß,
Leeloo

--
"Als es noch keine Computer gab, war das Programmieren noch relativ einfach." - Edsger W. Dijkstra
  1. echo $begrüßung;

    Fangen wir von vorne an: Ich baue mir mit Hilfe von DOMImplementation von PHP ein XML-Dokument in UTF-8. Damit auch jeder Inhalt der erstellten XML-Tags akzeptiert werden, muss ich sie maskieren, mittels htmlentites (sorry, ein anderer Weg ist mir grad nicht eingefallen).

    Nein, das ist nicht notwendig, da die notwendigen Maskierungen von den DOM-Funktionen selbst vorgenommen werden. Du übergibst einfach nur reinen Text in dem dafür vorgesehenen Parameter.
    htmlentities() ist auch die falsche Funktion, da XML nur für die 5 Zeichen & < > " ' Entities deklariert. Aber egal, ob du nun htmlentities() oder htmlspecialchars() verwendest, wird das Ergebnis von den DOM-Funktionen als reiner Text interpretiert und das einleitende & erneut maskiert.

    Bei Anwendung von saveXML() - also den generierten Baum als String speichern, werden scheinbar < und >, die im normalen Text enthalten sind, automatisch maskiert.

    Nicht nur scheinbar, das ist definiertes Verhalten.

    Das sind übrigens öffnende und schließende HTML-Tags, die mittels eines Editors eingegeben wurden -> d.h. Wohlgeformtheit bleibt erhalten. Ich weiß ganz genau, ich habe sie nicht maskiert. Um sie wieder zu ordentlichen Tags zu machen, muss ich sie mit html_entity_decode wieder umwandeln.

    Das heißt also, du möchtest diese Eingabe nicht als reinen Text betrachten sondern als XML-Fragment? Dann musst du das auch so bekanntgeben und DOMDocumentFragment->appendXML() benutzen.

    Dummerweise werden auf diesem Weg auch die einfachen größer und kleiner im Text (" 1 < 2 < 3 > 2 > 1") wieder zurück verwandelt.

    Anhand welcher Kriterien soll man denn, wenn man ein dummer Computer ist, unterscheiden, ob ein < nun die Einleitung eines Tags ist oder ein Text-Bestandteil? Oder andersrum, dass das eine &amp; zu einen Tag-Einleitung und das andere &amp; zu einem Textzeichen umzukodieren ist?

    Beim Laden des XML-Strings in ein neues XML-Dokument mittels new DomDocument und loadXML() sagt der:
    Warning: DOMDocument::loadXML(): xmlParseEntityRef: no name in Entity,
    DOMDocument::loadXML(): StartTag: invalid element name in Entity

    Das wird eines der in HTML aber nicht in XML vorhandenen Entities sein.

    echo "$verabschiedung $name";

    1. Hallo,

      echo $begrüßung;

      Fangen wir von vorne an: Ich baue mir mit Hilfe von DOMImplementation von PHP ein XML-Dokument in UTF-8. Damit auch jeder Inhalt der erstellten XML-Tags akzeptiert werden, muss ich sie maskieren, mittels htmlentites (sorry, ein anderer Weg ist mir grad nicht eingefallen).

      Nein, das ist nicht notwendig, da die notwendigen Maskierungen von den DOM-Funktionen selbst vorgenommen werden. Du übergibst einfach nur reinen Text in dem dafür vorgesehenen Parameter.
      htmlentities() ist auch die falsche Funktion, da XML nur für die 5 Zeichen & < > " ' Entities deklariert. Aber egal, ob du nun htmlentities() oder htmlspecialchars() verwendest, wird das Ergebnis von den DOM-Funktionen als reiner Text interpretiert und das einleitende & erneut maskiert.

      Zu Maskierung verwende ich jetzt htmlspecialchars($cont, ENT_QUOTES, "UTF-8");

      Ich hätte es gern weggelassen, wenn es beim hinzufügen des Strings zum DOM-Baum nicht immer Fehler gegeben hätte. Ich muss es maskieren, sonst gehts net.

      Das heißt also, du möchtest diese Eingabe nicht als reinen Text betrachten sondern als XML-Fragment? Dann musst du das auch so bekanntgeben und DOMDocumentFragment->appendXML() benutzen.

      Danke für den Tipp. Hantiere gerade damit rum. Um das Fragment dem Baum hinzufügen zu können, muss er ebenfalls utf8-kodiert werden. Also so:

        
       $f = $dom->createDocumentFragment();  
       $f->appendXML(utf8_encode($cont));  
       $dom->documentElement->appendChild($f);  
      
      

      Der Endstring, der nach Verwendung von $dom->saveXML(); entsteht, muss ebenfalls mit utf8_encode($xmlstring); codiert werden, sonst is nix mit neu laden als DOMXML, weil er dann rummeckert: "NOT PROPER UTF-8 ... bla ..."

      Das macht er auch, wenn er oben bei appendXML($cont); kein utf8_encode bekommt.

      Das htmlspecialchars($cont, ENT_QUOTES, "UTF-8"); an der selben Stelle führt auch nur zu Fehlermeldungen.

      Das Problem ist jetzt, dass er jetzt dort wieder Probleme hat mit den > und <. Wenn die nicht vorkommen, stören Umlaute zwar nicht, die kommen aber nur als wirrer unentzifferbarer Buchstabensalat (die kann ich hier nichtmal als Beispiel angeben, weil "vom W3C als „discouraged character“ gekennzeichnet") an, was auch nicht Sinn und Zweck ist. Beides zusammen nutzt mir auch nix, weil dann nämlich die > und < maskiert werden und nicht mehr als XML in den Baum eingehängt werden können.

      Gruß,
      Leeloo

      --
      "Als es noch keine Computer gab, war das Programmieren noch relativ einfach." - Edsger W. Dijkstra
      1. Hallo,

        Mit $myxml = utf8_encode(utf8_decode($text)); hab ich endlich diese Buchstabenkaudawelchs rausgeriegt. Alles doppelt gemoppelt, aber was solls ...

        Problem bleibt, wenn ein kleiner < oder größer > im Textbereich des XML-Bereiches vorkommt. Dann kommt nämlich jeder Parser durcheinander: Warning: DOMDocumentFragment::appendXML(): Entity: line 1: parser error : StartTag: invalid element name in ...

        Wenn ich vorher htmlspecialchars mache, dann werden natürlich auch die zum Tag gehörenden < und > maskiert.

        Gruß,
        Leeloo

        --
        "Als es noch keine Computer gab, war das Programmieren noch relativ einfach." - Edsger W. Dijkstra
        1. echo $begrüßung;

          Problem bleibt, wenn ein kleiner < oder größer > im Textbereich des XML-Bereiches vorkommt. Dann kommt nämlich jeder Parser durcheinander: Warning: DOMDocumentFragment::appendXML(): Entity: line 1: parser error : StartTag: invalid element name in ...

          Wenn ich vorher htmlspecialchars mache, dann werden natürlich auch die zum Tag gehörenden < und > maskiert.

          Ja, so ist das nun mal. Woher soll denn htmlspecialchars() wissen, was Code und was Daten ist? Wenn du Daten an die DOM-Funktionen übergibst, mach das unmaskiert, denn so wollen die das haben. Wenn du Code übergibst, dann nimm appendXML(), und sorge dafür, dass die im Code eingebettenten Daten den Regeln entsprechen. Dazu musst du die Daten vor dem Einbetten in den Code entsprechend behandeln, denn es handelt sich dabei um eienn Kontextwechsel. Du wirst also keine Erfolge verzeichnen, wenn du alles in den selben Topf wirfst und dann erwartest, dass der PC irgendwie intelligent das Richtige macht.

          echo "$verabschiedung $name";

          1. Hallo,

            Problem bleibt, wenn ein kleiner < oder größer > im Textbereich des XML-Bereiches vorkommt. Dann kommt nämlich jeder Parser durcheinander: Warning: DOMDocumentFragment::appendXML(): Entity: line 1: parser error : StartTag: invalid element name in ...

            Wenn ich vorher htmlspecialchars mache, dann werden natürlich auch die zum Tag gehörenden < und > maskiert.

            Ja, so ist das nun mal. Woher soll denn htmlspecialchars() wissen, was Code und was Daten ist? Wenn du Daten an die DOM-Funktionen übergibst, mach das unmaskiert, denn so wollen die das haben. Wenn du Code übergibst, dann nimm appendXML(), und sorge dafür, dass die im Code eingebettenten Daten den Regeln entsprechen. Dazu musst du die Daten vor dem Einbetten in den Code entsprechend behandeln, denn es handelt sich dabei um eienn Kontextwechsel. Du wirst also keine Erfolge verzeichnen, wenn du alles in den selben Topf wirfst und dann erwartest, dass der PC irgendwie intelligent das Richtige macht.

            ja, genau das ist das Problem: Tags like <p> werden genauso behandelt wie ein < oder > inmitten des Textes, die dann einen Parsingfehler verursachen, wenn sie nicht maskiert sind. Der Parser sieht sie ebenfalls als Tags an. Ich übergebe halt Code in validen Tags, nur dazwischen können als normaler Text halt < und > vorkommen, die mir dann die Probleme machen. Es ist zum heulen. Ich müsste das also verbieten, was nicht unbedingt eine feine Art ist ...

            Gruß,
            Leeloo

            --
            "Als es noch keine Computer gab, war das Programmieren noch relativ einfach." - Edsger W. Dijkstra