gpt4 book ai didi

带有 text() 和 SimpleXMLElement->xpath 的 php xpath 不符合 xpath 预期结果

转载 作者:可可西里 更新时间:2023-10-31 23:06:07 25 4
gpt4 key购买 nike

我正在尝试获取/td/span 的所有文本节点。

我正在尝试使用 xpath/td/span/text()

问题是它返回每个文本元素的所有文本节点(这里有两个,“193”和“120”,它返回两次“193120”,而不是在单独的元素中返回 193 和 120)。

我在任何在线工具上尝试了完全相同的 xpath,它工作正常,在 php 中,结果完全不同。

使用 SimpleXMLElement

$xhtmlSnippet = '<td><span>193<span>10</span><span></span><div>66</div><span>195</span><span>.</span><span>34</span><span>242</span><span></span>120<span>64</span></span></td>';

$xml = new SimpleXMLElement($xhtmlSnippet);

$xresult = $xml->xpath('/td/span/text()');

foreach($xresult as $xnode){
echo "<br /><br />NodeValue: " . $xnode;
}

给我:

NodeValue: 193120

NodeValue: 193120

这是它通过在线工具正常工作的示例(所有其他在线工具也提供预期的输出):

Working example in online tester

编辑:

使用 DOMDocument + DOMXPath,它似​​乎按预期工作:

    $dom = new DOMDocument;
$dom->loadXML($xhtmlSnippet);

$xpath = new DOMXPath($dom);

foreach ($xpath->query('/td/span/text()) as $textNode) {
echo "\n\nTextNode: " . $textNode->nodeValue;
}

给予:

TextNode: 193

TextNode: 120

最佳答案

SimpleXMLElement 只能表示元素和属性,可以单独表示,也可以表示相同类型的兄弟元素的集合。 ->xpath() method返回一个 SimpleXMLElement 对象数组,允许它们成为非兄弟节点,但不允许任何其他节点类型。

因此,表达式 /td/span/text()匹配两个文本节点,但将它们作为代表其父元素的对象返回,在本例中恰好是相同的 <span>元素,两次为您提供具有相同对象的数组。

难题的其余部分是,当您将 SimpleXML 元素转换为字符串时,它将所有直接后代文本和 CDATA 节点合并为一个字符串,因此 193120粘在一起。

因此输出为193120 , 两次。

(这绝对是不符合直觉的行为,尽管很难确切地知道 SimpleXML 在这种情况下应该做什么;如果 XPath 表达式解析为元素或属性以外​​的其他内容,也许产生错误会更好)。


由于 DOM API 具有可能存在于 XML 中的每种节点的对象,并且 PHP 包含该 API 的完整实现,因此 XPath 表达式将在那里按预期工作。更重要的是,SimpleXML 和 DOM 对象实际上都是相同内部内存结构的包装器,因此您可以使用 dom_import_simplexml() 编写将两者组合的操作。和 simplexml_import_dom() .

作为一个稍微不雅的示例,如果您想在您已经使用 SimpleXML 遍历过的元素的上下文中运行 XPath 表达式,您可以这样做:

$dom_node = dom_import_simplexml($simplexml_node);
$dom_xpath = new DOMXPath($dom_node->ownerDocument);
$dom_xpath_result = $dom_xpath->query('span/text()', $dom_node);

foreach($dom_xpath_result as $xnode){
echo "<br /><br />NodeValue: " . $xnode->nodeValue;
}

显然,您可以根据需要将其包装到一个函数中。另请注意,由于您的表达式从文档根目录(前导 /)开始,因此实际上下文无关紧要,这就是为什么我在上面使用了稍微不同的表达式。

关于带有 text() 和 SimpleXMLElement->xpath 的 php xpath 不符合 xpath 预期结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19847451/

25 4 0
文章推荐: php - 将 Symfony\Console 用于交互式 php cli 应用程序
文章推荐: html - 在
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com