SimpleXML

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • SimpleXML

    Folgendes Problem. Ich möchte einen XPath-Ausdruck auf einem wohlgeformten XML-String auswerten.

    Dieses XML ist aber nicht valide, denn es handelt sich nur um ein Fragment einer größeren XML-Datei.

    Ich habe das mit SimpleXML und PHP 5.1 probiert und natürlich nur Fehlermeldungen erhalten.

    Hier ist der Code:
    PHP-Code:
    $xml simplexml_load_string($string'SimpleXMLElement'LIBXML_NOERROR);
    $xpath_result $xml->xpath($xpath); 
    Ergebnis: simplexml_load_string liefert boolean(false) als Rückgabewert.

    Gibt es eine Möglichkeit das trotzdem irgendwie zu realisieren?

  • #2
    Bitte gib mal Stück von Deinem XML dazu.

    Chris
    www.software-developers-home.de

    Kommentar


    • #3
      Re: SimpleXML

      wie wäre es die NO-ERROR-Direktive mal wegzulassen?!

      Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

      bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
      Wie man Fragen richtig stellt

      Kommentar


      • #4
        Bitteschön.

        Code:
        <?xml version="1.0" encoding="us-ascii"?>
        <!DOCTYPE dokument PUBLIC "FOO" "Foo.dtd">
        <dokument id="CDATA" abschnitt="CDATA">
          <lmeta light.ebene1.nr="CDATA" light.ebene2.nr="CDATA"/>
          <ameta ai.hb.ebene1="CDATA" ai.hb.ebene2="CDATA"/>
          <st><se>CDATA</se><lg>CDATA</lg></st>
          <kopf>
          <titel>CDATA&amp;amthinsp;&amp;sol;&amp;thinsp;&amp;thinsp;CDATA&amp;szlig;CDATA</titel>
          </kopf>
          <inhalt>
          <table frame="CDATA" typesize="CDATA">
          <tgroup cols="CDATA" align="CDATA" colsep="CDATA" rowsep="CDATA" tgroupstyle="CDATA">
            <colspec colnum="CDATA" colname="CDATA" colsep="CDATA" colwidth="CDATA"/>
            <colspec colnum="CDATA" colname="CDATA" colsep="CDATA" colwidth="CDATA"/>
            <tbody valign="CDATA">  <row rowsep="CDATA">
            <entry colname="CDATA" rowsep="CDATA" valign="CDATA" align="CDATA"><p><f>CDATA</f></p></entry>
            <entry colname="CDATA" rowsep="CDATA" valign="CDATA" align="CDATA">
              <p><liste><item foo="CDATA">CDATA</item></liste></p>
            </entry>
            </row>
            </tbody>
            </tgroup></table>
          </inhalt>
          <typ.gliederung></typ.gliederung>
        </dokument>
        Ich habe den Auszug ein wenig gekürzt und für die Lesbarkeit Zeilenumbrüche eingefügt. Eine DTD dazu existiert nicht. Es kann außerdem vorkommen, dass die Eingabedaten keine Doctype-Deklaration oder XML-Header enthalten.

        @ghost Das NO_ERROR habe ich eingefügt, weil ich sowieso weiß, dass das Dokument nicht valide ist, die Entitäten nirgends deklariert sind, oder sogar mal der Doctype oder Header fehlt. Das ist mir schon klar. Aber daran kann ich nichts ändern, weil der XML-Quellcode von einer externen Quelle stammt und die Daten unverändert durchgereicht werden müssen.
        Theoretisch braucht das Dokument also auch gar nicht valide sein, denn alles was ich will ist einen XPath-Ausdruck ausführen und dazu sollte es (theoretisch) reichen, wenn das Dokument wohlgeformt ist.

        Nur: wie macht man das mit einem XML-Fragment wie diesem?
        Zuletzt geändert von Marcusson; 25.07.2006, 12:10.

        Kommentar


        • #5
          Hmm... ich denke ich habe es soweit hingekriegt. ABER mein Problem ist, dass die Entities automatisch umgewandelt bzw. entfernt werden. Genau das soll aber gerade nicht passieren.
          Leider wird die Option LIBXML_NOENT laut Handbuch von der Funktion saveXML in PHP 5.1 nicht unterstützt.

          Habe schon versucht dieses Verhalten über andere Parameter abzuschalten, aber die Dokumentation auf php.net ist an diesem Punkt zur Zeit sehr lückenhaft.

          Kennt jemand einen anderen Weg?
          PHP-Code:
                  libxml_use_internal_errors(true);
                  
          $xml = new DOMDocument('1.0''UTF-8');
                  
          $xml->recover true;
                  
          $xml->resolveExternals false;
                  
          $xml->strictErrorChecking false;
                  
          // das hat leider keine Auswirkungen auf das Endergebnis
                  
          $xml->substituteEntities false;
                  
          $xml->validateOnParse false;
                  
          $xml->formatOutput false;
                  
          $xml->preserveWhiteSpace true;
                 
          // der zweite Parameter ist auf php.net leider nicht dokumentiert
                  
          $xml->loadXML($string,LIBXML_NOENT);
                  
          $xpath = new domXPath($xml);
                  
          $xpath_result $xpath->query($query);

                  if (
          is_scalar($xpath_result)) {
                      return 
          $xpath_result;
                  } else {
                      
          $replace "";
                      for (
          $i=0;$i<$xpath_result->length;$i++)
                      {
                          
          $newDom = new DOMDocument;
                          
          $newDom->recover true;
                          
          $newDom->resolveExternals false;
                          
          $newDom->strictErrorChecking false;
                          
          $newDom->substituteEntities false;
                          
          $newDom->validateOnParse false;
                          
          $newDom->formatOutput false;
                          
          $newDom->preserveWhiteSpace true;
                          
          $a $newDom->appendChild($newDom->importNode($xpath_result->item($i),true));
                          
          $replace .= $newDom->saveXML($a);
                      }
                      return 
          $replace;
                  } 

          Kommentar

          Lädt...
          X