T-Rex: PHP DomDocument link tags sind leer

Moin,

hab hier einen xml:

    <stichwort nid="1">
        <titel>Abberufbarkeit</titel>
        <text>A. bezeichnet das
                <link nid="1226">Recht</link> einer Wählerschaft, gewählte Mitglieder der
                <link nid="872">Legislative</link>,
                <link nid="509">Exekutive</link> oder
                <link nid="746">Judikative</link> vor Ablauf ihrer
                <link nid="61">Amtsperiode</link> abzuwählen oder abzuberufen. A. ist bspw. in den
                <link nid="1537">Verfassungen</link> verschiedener US-amerikanischer Einzelstaaten vorgesehen.
            </text>
    </stichwort>

Das steht in einer Datei. Diese lade ich in ein DomDocument Objekt und versuche die links raus zu filtern:

		$strContent = file_get_contents( $strFile );
		$objDom = new DomDocument();
		@$objDom->loadHTML( $strContent );
		$arLinks = $objDom->getElementsByTagName('link');

Jedoch sind alle Links leer:

echo $arLinks[0]->C14N()

Ersetze ich jedoch alle links mit kinl, dann funktioniert es:

		$strContent = file_get_contents( $strFile );
		$strContent = str_replace("<link","<kinl", $strContent);
		$strContent = str_replace("</link>","</kinl>", $strContent);
		$objDom = new DomDocument();
		@$objDom->loadHTML( $strContent );
		$arLinks = $objDom->getElementsByTagName('kinl');
		echo $arLinks[0]->C14N()  //--- Recht

Ich hab keine Ahnung wieso...

Gruße xeR-T

  1. Hallo T-Rex,

    @$objDom->loadHTML( $strContent );
    

    diese Zeile ist schuld. Doppelt!

    Fehler 1: Das @ versteckt den Fehler 2 vor Dir. Nimm es weg und betrachte die diversen Fehlermeldungen, die dann erscheinen. Die sollten Dich vom Holzweg auf eine gute, sichere Straße bringen. Vergleiche auch mal die Meldungen mit denen, die kommen, wenn Du link durch knil oder sowas ersetzt.

    Fehler 2: Na? Wer weiß denn sowas? Ist es
    (A) die fehlende Zuweisung des Rückgabewertes an $objDom
    (B) die falsche Methode zum Laden des Dokuments
    (C) die fehlende LIBXML_NOXMLDECL Option (als 2. Parameter der Lademethode)?

    Im Übrigen:

    echo $arLinks[0]->C14N()  //--- Recht
    

    Parse error: syntax error, unexpected end of file
    Wrong result: Da kommt nicht nur "Recht" heraus.

    echo $arLinks[0]->textContent;)  //--- Recht
    

    Rolf

    --
    sumpsi - posui - obstruxi
    1. $objDom->loadXML( $strContent, LIBXML_NOXMLDECL );

      Das verhalten bleibt das gleiche. Die link Tags werden leer ausgegeben.

      Gruß leerer T-Rex

      1. Hallo T-Rex,

        nur eine der drei Antworten war richtig: B 😉. Die Option LIBXML_NOXMLDECL bezieht sich auf das Speichern eines Dokuments als String.

        Ich bin ratlos, mit loadXML funktioniert es bei mir. Mit PHP Versionen 5.6 bis 8. Sind bei Dir noch andere Rahmenbedingungen?

        https://sandbox.onlinephpfunctions.com/code/5a5d37e14ea73a1723df12dea9bf5458946ed8cd

        Dass ich DOMDocument statt DomDocument geschrieben habe, ist egal. Das ist in PHP nicht case-sensitive.

        Rolf

        --
        sumpsi - posui - obstruxi
  2. Ich hab keine Ahnung wieso...

    das link-Element in html kennt kein Attribut nid. Vielleicht ignoriert die loadHTML-Methode deshalb das link-Element

    Das kinl-Element hat im html-Kontext keine Bedeutung. Vielleicht akszeptiert die loadHTML-Methode deshalb das kinl-Element.

    P.S.

    Wie es aussieht, ist mit dem link-Elemnet im XML-Dokement nicht das link-Element im html-Kontext gemeint, sondern ein a-Element

  3. Hallo,

    Vermutung: der Objekttyp ist dem Parser unbekannt?

    Da hilft manchmal eine vorgeschaltete Zeile mit dem passenden Objekttyp aka Dokumenttyp.

    LG
    Ralf

  4. Hello,

    		$strContent = file_get_contents( $strFile );
    		$objDom = new DomDocument();
    		@$objDom->loadHTML( $strContent );
    		$arLinks = $objDom->getElementsByTagName('link');
    

    In meinen Parser-Applikationen habe ich immer stehen:

    function get_linklist($page, &$_exceptions = NULL)
    {
    	$dom = new DOMDocument('1.0', 'utf-8');
    	$dom->encoding = 'utf-8';
    	$dom->validateOnParse = TRUE;
    	$dom->strictErrorChecking = true ;
    	$dom->preserveWhiteSpace = true;
    	$dom->resolveExternals = true;
    	
    	set_error_handler('handleError', E_WARNING);
    	$dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">' . "\r\n" . $page);
    	restore_error_handler();
    	
    	$a_nodelist = $dom->getElementsByTagName('a');
    
    ## ...  
    
    

    In $page ist die Seite als String drin.

    Glück Auf
    Tom vom Berg

    --
    Es gibt nichts Gutes, außer man tut es!
    Das Leben selbst ist der Sinn.
    1. Hallo TS,

      sicherlich sinnvolle Optionen, aber ich würde gern wissen, ob ich die richtig verstanden habe.

      resolveExternals
      Set it to true to load external entities from a doctype declaration. This is useful for including character entities in your XML document.

      strictErrorChecking
      Throws DOMException on errors. Default to true.

      validateOnParse
      Loads and validates against the DTD. Default to false.

      resolveExternals scheint mir für HTML irrelevant. Bei XML nicht, aber T-Rexens XML Fragment enthält sowas nicht.

      strictErrorChecking setzt einen try-catch Block voraus, sonst fliegst Du bei Fehlern komplett aus dem Script. Hast Du den außerhalb deiner Funktion?

      validateOnParse setzt voraus, dass eine DTD da ist. Soweit ich weiß, gibt es für HTML 5 keine DTD mehr, aber für HTML 4 gab's noch eine. Das setzt dann einen entsprechenden HTML 4 Doctype voraus. Aber T-Rex macht XML

      Wie auch immer, das Umschalten der strictErrorChecking und validateOnParse-Flags hat in der Sandbox keinen Unterschied gemacht.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Hello,

        Wie auch immer, das Umschalten der strictErrorChecking und validateOnParse-Flags hat in der Sandbox keinen Unterschied gemacht.

        Aber die Angabe der Version und der Codierung sollte eine Wirkung haben. Bei mir hat der Parser dann auch erst funktioniert, als ich den Content-Type nochmal als Meta-Angabe davorgestanzt hatte.

        Ich benutze das so bis heute auf meinem Webserver in meinem automatischen Downloader für neue Software-Releases.

        Meine Meldung sollte auch nur eine Kurzanregung sein, keine fertige Lösung.

        Glück Auf
        Tom vom Berg

        --
        Es gibt nichts Gutes, außer man tut es!
        Das Leben selbst ist der Sinn.
  5. Lieber T-Rex,

    hab hier einen xml: [...] @$objDom->loadHTML( $strContent );

    da hätte ich jetzt eine andere Methode erwartet, nämlich loadXML. In HTML haben <link>-Elemente nämlich keinen Inhalt, weil sie dort so definiert sind.

    Liebe Grüße

    Felix Riesterer

    1. Hello lieber Felix,

      hab hier einen xml: [...] @$objDom->loadHTML( $strContent );

      da hätte ich jetzt eine andere Methode erwartet, nämlich loadXML. In HTML haben <link>-Elemente nämlich keinen Inhalt, weil sie dort so definiert sind.

      Aufmerksam, aufmerksam!

      Habe ich eben ganz übersehen, dass er nach Inhalt und nicht nach Attributen suchte...

      Glück Auf
      Tom vom Berg

      --
      Es gibt nichts Gutes, außer man tut es!
      Das Leben selbst ist der Sinn.