Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP Dom文档:忽略脚本标记和注释获取文本内容_Php_Xml_Dom - Fatal编程技术网

PHP Dom文档:忽略脚本标记和注释获取文本内容

PHP Dom文档:忽略脚本标记和注释获取文本内容,php,xml,dom,Php,Xml,Dom,我使用dom doc从数据库中加载html,如下所示: $doc = new DOMDocument(); @$doc->loadHTML($data); $doc->encoding = 'utf-8'; $doc->saveHTML(); 然后我通过执行以下操作获得正文: $bodyNodes = $doc->getElementsByTagName("body"); $words = htmlspecialchars($bodyNodes->item(0)-

我使用dom doc从数据库中加载html,如下所示:

$doc = new DOMDocument();
@$doc->loadHTML($data);
$doc->encoding = 'utf-8';
$doc->saveHTML();
然后我通过执行以下操作获得正文:

$bodyNodes = $doc->getElementsByTagName("body");
$words = htmlspecialchars($bodyNodes->item(0)->textContent);
我得到的单词包含了
中的所有内容。还包括
之类的内容。
如何删除它们并只保留真实的文本内容?

您必须访问所有节点并返回它们的文本。如果其中一些包含其他节点,也可以访问它们

这可以通过以下基本递归算法完成:

extractNode:
    if node is a text node or a cdata node, return its text
    if is an element node or a document node or a document fragment node:
        if it’s a script node, return an empty string
        return a concatenation of the result of calling extractNode on all the child nodes
    for everything else return nothing
实施:

function extractText($node) {    
    if (XML_TEXT_NODE === $node->nodeType || XML_CDATA_SECTION_NODE === $node->nodeType) {
        return $node->nodeValue;
    } else if (XML_ELEMENT_NODE === $node->nodeType || XML_DOCUMENT_NODE === $node->nodeType || XML_DOCUMENT_FRAG_NODE === $node->nodeType) {
        if ('script' === $node->nodeName) return '';

        $text = '';
        foreach($node->childNodes as $childNode) {
            $text .= extractText($childNode);
        }
        return $text;
    }
}
这将返回给定$node的textContent,忽略脚本标记和注释

$words = htmlspecialchars(extractText($bodyNodes->item(0)));
在这里试试:

您可以使用它

借用用于上述示例的HTML arnaud:

$html = <<< HTML
<p>
    test<span>foo<b>bar</b>
</p>
<script>
    ignored
</script>
<!-- comment is ignored -->
<p>test</p>
HTML;
将输出()


你的意思是递归提取
中每个元素的文本内容?只提取有意义的文本内容,不包括Java脚本或其他html注释等,这些都不是有用的数据。我已经添加了算法的快速描述。此函数有助于。它实际上能够识别并将单词的句子分割成一个字符串。@nuttynibbles它不识别单词,也不识别句子。XPath是XML的查询语言。它不知道XML文档的内容,只知道结构。看见
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->loadHtml($html);

$xp    = new DOMXPath($dom);
$nodes = $xp->query('/html/body//text()[
    not(ancestor::script) and
    not(normalize-space(.) = "")
]');

foreach($nodes as $node) {
    var_dump($node->textContent);
}
string(10) "
    test"
string(3) "foo"
string(3) "bar"
string(4) "test"