在有效的PHP查询中转换Javascript XPath()XPath |规范化JS XPath-->;PHP
这是Javascript中有效的XPath:在有效的PHP查询中转换Javascript XPath()XPath |规范化JS XPath-->;PHP,php,javascript,xml,dom,xpath,Php,Javascript,Xml,Dom,Xpath,这是Javascript中有效的XPath: id("priceInfo")/div[@class="standardProdPricingGroup"]/span[1] 这将转换为有效的PHP XPath,并与DOMXPath->query()一起使用 您知道已经进行此转换的库或自定义组件吗 您知道列出这两种语法差异的可用文档吗 我主要担心的是可能会有很多差异,我希望找出这些差异,但我很难找出这些差异 这个问题也可以用不同的方式提出:既然Javascript可以有不同的有效XPath格式,那
id("priceInfo")/div[@class="standardProdPricingGroup"]/span[1]
这将转换为有效的PHP XPath,并与DOMXPath->query()一起使用
@萨拉特指出,如果记录的输入具有有效的DTD,那么有效的Javascript XPath查询在PHP中可以正常工作(@Dimitre Novatchev在评论中提到了这一点,但忽略了其重要性)。不幸的是,我无法控制输入DTD,因此现在我必须研究一种方法来克服这一问题,或者找到一种即使没有有效DTD也能工作的解决方案。只是看到Salath实际上回答了相同的问题,但要考虑到您的评论并强调这一点: 您不需要指定任何DTD。只要使用
DOMDocument::loadHTML
或DOMDocument::loadHTMLFile
函数,HTMLid
属性实际上是为xpathid()函数注册的。使用中给出的演示HTML,加载文档时甚至会出现错误:
警告:DOMDocument::loadHTMLFile():ID priceInfo已在中定义
这已经表明这是一个真正的ID属性,因为它抱怨重复。相关的示例代码如下所示:
$xpath = 'id("priceInfo")/div[@class="standardProdPricingGroup"]/span[1]';
$doc = new DOMDocument();
$doc->loadHTMLFile(__DIR__ . '/../data/file-11796340.html');
$xp = new DOMXPath($doc);
$r = $xp->query($xpath);
echo $xpath, "\n";
echo $r ? $r->length : 0, ' elements found', "\n";
if (!$r) return;
foreach($r as $node) {
echo " - ", $node->nodeValue, "\n";
}
输出为:
id("priceInfo")/div[@class="standardProdPricingGroup"]/span[1]
1 elements found
- hello
如果需要更多控制,请首先运行xpath,将所有HTMLid
属性标记为xpath的id:
$r = $xp->query("//*[@id]");
if ($r) foreach($r as $node) {
$node->setIdAttribute('id', true);
}
然后,您可以对id()
函数使用相同的xpath,无需更改它。您不能在表达式的开头将id(“…”
转换为/*[@id=“…”][1]
例如,如果您可以假设id(…)
表达式中没有任何括号:
$queryRewritten = preg_replace('/^id\(([^\)]+)\)/','//*[@id=$1][1]',$query);
编辑:更正了替换,id()i必须是表达式中的第一个这不是完整答案,但它太大,无法作为注释,可能会对您有所帮助
如果您可以控制输入XML,那么您可以在XML文档本身中通过使用XML:
作为id
属性的前缀来显式声明属性,而不是使用DTD来声明id
属性
例如,如果您有
<foo id="x27"/>
改成
<foo xml:id="x27"/>
然后id()函数会将该属性识别为正式的XMLid
类型,而不仅仅是名为id
的属性
我知道这个“技巧”可以在Saxon处理器上使用,但我必须承认我还没有在PHP上尝试过
这是一个很好的问题!看起来没有任何文档(至少不是通过粗略的谷歌搜索)。我很高兴看到这个问题的答案。第一个表达式是合法的XPath表达式。但是,要使Xpath函数id()
工作,XML必须有DTD,DTD中的元素定义必须有属性,并且必须有id
关键字。@DimitreNovatchev:那么/
到/
的翻译又如何呢?@choroba Java在整个问题中没有提到一次。另外,id()
是您链接到的规范中提到的一个节点集函数。我认为javascript的xpath与php没有太大区别。我的意思是xpath语言应该是相同的,对吗?您可以添加您特别指的javascript xpath吗?对于php来说,很明显,只有一个。但是,等等,不止一个,但是你已经写过了,你指的是标准的DOMDocument扩展,对吧。这很有帮助,但我很好奇将来还会出现什么其他未记录的东西。它不是真正的未记录的东西,XPATH规范对这种行为非常清楚。未记录的部分是关于浏览器DOM引擎隐式地将Doctype应用于HTML DOM。@Pentium10也许您需要更明确地说明您试图实现的目标。我在更新的问题的最后一行中说,我想找到一个独立于DTD的解决方案。除了使用不同名称空间前缀的文档,这可能会欺骗wpath引擎。或者是为属性指定默认隐含值的DTD(对于HTML来说,这种情况永远不会出现)。您应该知道,PHP允许您指定xml:id
属性的名称,而不考虑输入(并且不更改它)。一个例子是
<foo xml:id="x27"/>