这是Javascript中的有效XPath:
id("priceInfo")/div[@class="standardProdPricingGroup"]/span[1]
这将转换为有效的PHP以便与DOMXPath一起使用-> XPath ()是
//*[@id="priceInfo"]//div[@class="standardProdPricingGroup"]//span[1]
我主要担心的是可能会有很多不同之处,我希望找出这些不同之处,但我在找出这些不同点时遇到了问题。
这个问题也可以用不同的方式提出:由于Javascript可以有不同的有效XPath格式,如何将它们规范化以与PHP.一起工作
其中一个更新还提到,如果存在包含此定义的有效XPath,则id()函数是有效的DTD。我没有能力控制输入DTD,如果有一种方法可以找到一个不需要任何特定DTD就能工作的解决方案,那就太棒了。
更新:
我想用一个算法把第一种格式转换成第二种格式。我的输入是第一个,而不是第二个。不能改变这一点。
正如@Nison Maël指出的,第二种格式是有效的Javascript XPath,如下所示:http://jsbin.com/elatum/2/edit这不幸地增加了Javascript XPath“碎片”的问题。
@salathe指出,如果文档中的输入具有有效的XPath,那么有效的Javascript DTD查询在PHP中工作得很好( @Dimitre Novatchev在评论中提到了这一点,但忽略了重要性)。不幸的是,我无法控制输入的DTD,所以现在我必须研究一种方法来克服这个问题,或者找到一种即使没有有效的DTD也能工作的解决方案。
发布于 2012-08-06 03:19:32
只是看到Salathe实际上回答了同样的问题,但是考虑到你的评论并强调一下:
您不需要指定任何DTD。只要使用DOMDocument::loadHTML
或DOMDocument::loadHTMLFile
函数,就会为xpath id()
函数实际注册HTML id
属性。使用http://jsbin.com/elatum/2/edit中给出的演示超文本标记语言,您甚至会在加载文档时收到错误:
警告: 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,将所有HTML属性标记为id
的ID:
$r = $xp->query("//*[@id]");
if ($r) foreach($r as $node) {
$node->setIdAttribute('id', true);
}
然后,您可以将相同的xpath与id()
函数一起使用,无需更改它。
发布于 2012-08-07 21:23:41
你不能在表达式的开头就把id("...")
转换成//*[@id="..."][1]
吗?
例如,if可以假设在id(...)
表达式中没有任何括号:
$queryRewritten = preg_replace('/^id\(([^\)]+)\)/','//*[@id=$1][1]',$query);
编辑:更正了替换,id()必须是表达式中的第一个
发布于 2012-08-09 07:46:10
这不是一个完整的答案,但它太大了,不能作为评论,它可能会对你有一点帮助。
如果可以控制输入XML,那么可以在id
文档本身中显式地声明它们,方法是在id
属性前面加上xml:
前缀,而不是使用DTD来声明。
例如,如果您有
<foo id="x27"/>
并将其更改为
<foo xml:id="x27"/>
然后,id()函数会将该属性识别为正式的XMLid
类型,而不仅仅是名称为id
的属性。
我知道这个“技巧”在Saxon处理器上有效,但我必须承认我还没有在PHP上尝试过。
https://stackoverflow.com/questions/11796340
复制相似问题