• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

domDocument inhalt von Tag auslesen

bonimo

Neues Mitglied
Hallo,

nehmen wir an ich hätte folgenden code:

HTML:
<div>Irgend ein Text <strong>ein anderer Text</strong></div>

und möchte dann nur den Inhalt des div Containers, also in diesem Fall "Irgend ein Text" auslesen.

Wenn ich jetzt allerdings die nodeValue dieses Div´s auslesen möchte, wird der Text im <strong> - tag mitausgegeben:

PHP:
$doc = new DOMDocument();
$doc->loadHTMLFile("test.html");
$dom->preserveWhiteSpace = false;
$doc->getElementsByTagName("div")->item(0)->nodeValue;

Code:
Ausgabe: "Irgend ein Text ein anderer Text"

Wie kann ich denn erreichen dass nur der content dieses div tags und nicht auch noch der von dessen childnodes ausgelesen wird?

lg und thx
Marek
 
Du wählst mit deinem Code den ersten <div>-Knoten aus, nicht den ersten Knoten *innerhalb* des <div>-Knotens (der wäre vom Typ XML_TEXT_NODE).

PHP:
<?php

$doc = new DOMDocument();

$doc->loadHTML('<div>Irgend ein Text <strong>ein anderer Text</strong></div> ');
$doc->preserveWhiteSpace = false;

echo $doc->getElementsByTagName("div")
        ->item(0)    // der erste <div>-Knoten
        ->firstChild // XML_TEXT_NODE
        ->nodeValue;
 
Zuletzt bearbeitet:
Hey super danke das hat mir schon sehr weiter geholfen.

Allerdings hab ich jetzt das Problem. Wenn ein parent kein anderen content als children hat, wird als nodeValue der Inhalt aller children ausgegeben.

Hier zur verdeutlichung:

HTML:
<div><p>testtext</p><div>irgendwas anderes</div></div>

als nodeValue des ersten Div´s wird mir dann "testtextirgendwas anderes" ausgegeben.

Ist das ein Bug oder soll das so sein? Wenn ja wie kann ich das denn verhinden?

lg
Marek
 
Also im groben geht es darum den Content (ohne HTML-Tags) statistisch zu erfassen und auszuwerten. Also unter anderem Häufigkeit, Reihenfolge, oft zusqammen verwendete Worte, oft aufeinander folgende worte usw...

Dazu möchte ich erstmal den eigentlichen Content sauber vom HTML-Code trennen. Wichtig ist mir jedoch dass der Zusammenhang bestehen bleibt, also obwohl ich den gesamten Content vom Html-Code getrennt habe möchte ich weiterhin nachvollziehen können welcher content in welchen tag in welcher depth in welcher reihenfolge stand.

Ich hab mir da gedacht dass das domdocument die beste lösung ist, leider verfälscht das oben genannte problem diese statistik ziemlich - immer wenn ich die nodeValue von contentleeren tags(content im sinne von text) wie beim oben genannten beispiel ausgeben möchte, wird der content der children bzw sogar vom chronologisch nächsten tag.
 
Ja, wobei mir immer noch nicht klar ist, was das Ziel und was das Problem ist. Die Beschreibung war für meine Begriffe zu wenig genau. Aber das macht nichts, denn ich glaube, die Schwierigkeiten hängen eher mit einem Missverständnis des Aufbaus eines HTML/XML-Dokuments zusammen.

In einem Dokument befindet sich *alles* innerhalb eines Knotens.

PHP:
<?php

function nodeTypeToString($nodeType)
{
    $map = array(
         1 => 'XML_ELEMENT_NODE',
         2 => 'XML_ATTRIBUTE_NODE',
         3 => 'XML_TEXT_NODE',
         4 => 'XML_CDATA_SECTION_NODE',
         5 => 'XML_ENTITY_REFERENCE_NODE',
         6 => 'XML_ENTITY_NODE',
         7 => 'XML_PROCESSING_INSTRUCTION_NODE',
         8 => 'XML_COMMENT_NODE',
         9 => 'XML_DOCUMENT_NODE',
        10 => 'XML_DOCUMENT_TYPE_NODE',
        11 => 'XML_DOCUMENT_FRAGMENT_NODE',
        12 => 'XML_NOTATION_NODE'
    );

    if (isset($map[$nodeType])) {
        return $map[$nodeType];
    }

    return 'UNKNOWN';
}

header('Content-Type: text/html; charset=UTF-8');

$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;

// Auf XML umgestellt (fügt nicht automatisch HTML-Wurzeltags hinzu)
$doc->loadXML('<div>Irgend ein Text<!--Kommentar-->
    <strong>ein <![CDATA[<huhu>]]> anderer Text</strong>
    </div>');

function rec(DOMNode $node, $indent = 0)
{
    if ($node->hasChildNodes()) {
        foreach ($node->childNodes as $child) {
            echo '<tr>';
            echo '<td>' . str_repeat('&nbsp;', $indent)
                    . $child->nodeName . '</td>';
            echo '<td>' . nodeTypeToString($child->nodeType) . '</td>';

            $nv = htmlspecialchars($child->nodeValue);

            $nv = str_replace(array("\n", "\r", "\t", ' '),
                              array('\n', '\r', '\t', '&nbsp;'), $nv);

            if ($nv === '') {
                $nv = '{empty}';
            } else {
                $nv = '"' . $nv . '"';
            }

            echo '<td>' . $nv . '</td>';
            echo '</tr>';
            rec($child, $indent + 4);
        }
    }
}

echo '<table border="1">';
echo '<tr><th>nodeName</th><th>nodeType</th><th>nodeValue</th></tr>';
rec($doc);
echo '</table>';
 
Zurück
Oben