在有效的PHP查询()中转换Javascript XPath()XPath规范化JS XPath->PHP?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (3)
  • 关注 (0)
  • 查看 (93)

这是Javascript中的有效XPath:

id("priceInfo")/div[@class="standardProdPricingGroup"]/span[1]

这变成了与DOMXPath->Query()一起使用的有效PHPXPath

//*[@id="priceInfo"]//div[@class="standardProdPricingGroup"]//span[1]
  1. 是否知道任何已经执行此转换的库或自定义组件?
  2. 知道列出这两种语法差异的可用文档吗?

我主要担心的是可能会有很多不同之处,我想找出这些差异,而我也有问题去找出这些差异。

这个问题也可以以不同的方式提出:因为Javascript可以有不同的有效XPath格式,所以如何将它们规范化以使用PHP。

其中一个更新还提到,如果存在包含此定义的有效DTD,则id()函数是有效的XPath。我对输入的DTD没有权力,如果有一种方法可以在没有任何特定DTD的情况下找到一个可行的解决方案,那就太棒了。

最新情况:

我想用算法将第一种格式转换为第二种格式。我的输入是二而不是三。改变不了这个。

第二格式是有效的JavascriptXPath,如下所示:http://jsbin.com/elatum/2/

不幸的是,这只会增加JavascriptXPath“碎片”的问题。

如果所记录的输入具有有效的DTD,那么有效的Javascript XPath查询在PHP中工作得很好。不幸的是,我无法控制输入DTD,所以现在我必须研究一种克服这一问题的方法,或者找到一个即使没有有效DTD也能工作的解决方案。

提问于
用户回答回答于

不需要指定任何DTD。只要使用DOMDocument::loadHTMLDOMDocument::loadHTMLFile函数,HTMLid属性实际上是为XPath注册的。id()功能。中给出的演示HTMLhttp://jsbin.com/elatum/2/编辑,甚至在加载文档时会出现错误:

警告:DOMDocument::loadHTMLFile():IDpriceInfo已在...

这已经是一个迹象,表明这是一个真正的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);
}

然后,可以将相同的XPath用于id()功能,无需更改。

用户回答回答于

如果控制了输入XML,那么就不用使用dtd来声明id属性,可以在xml文档本身中通过前缀显式声明它们。id属性xml:...

例如,如果xml

<foo id="x27"/>

并将其改为

<foo xml:id="x27"/>

然后id()函数将该属性识别为正式的xml。id类型,而不仅仅是作为一个具有名称的属性。id...

我知道这个“技巧”可以在Saxon处理器上工作,但我必须承认,我还没有尝试过PHP。

W3CXML:ID

用户回答回答于

例如,如果可以假设在id(...)表达方式:

$queryRewritten =   preg_replace('/^id\(([^\)]+)\)/','//*[@id=$1][1]',$query);

样本代码

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励