【问题标题】:php xpath with dom how to write shorter querys带有dom的php xpath如何编写更短的查询
【发布时间】:2017-01-05 08:50:34
【问题描述】:

我需要取出数据的 xml 文件很大,并且在孩子中有很多内部孩子。我需要查询的 XML 看起来像图片中的样子,并且它有更多的 Ref 孩子。 xml structure

我需要获取具有正确 Info->ID 的公司节点。该节点有 3 个 Ref 节点,我需要从具有正确 Who 的节点获取 Date。

我得到了这个丑陋的代码:

$query_pod = "//Seller/Company/Info/ID[ID = 'IV'] | //Seller/Company/Ref/Who[Who = 'VA'] | //Seller/Company/Ref/Date";
foreach ($xpath->query( $query_pod ) as $pod)
{
    $pod_dates = $xpath->query( "//Seller/Company/Ref/Who[Who = 'VA'] | //Seller/Company/Ref/Date", $pod );
    $pod_date = $pod_dates->item(0)->nodeValue;
}

我试过更短,但我无法像这样在 [] 中获取选择元素:

$query_pod = "//Seller/Company/Info[ID = 'IV']";
foreach ($xpath->query( $query_pod ) as $pod)
{
    $pod_dates = $xpath->query( "//Seller/Company/Ref/Date[Who = 'VA'], $pod );
    $pod_date = $pod_dates->item(0)->nodeValue;
}

有人可以帮忙吗?我是 xpath 的新手。

【问题讨论】:

  • $pod_dates = $xpath->query("//Seller/Company/Ref/Date[Who = 'VA']", $pod );我的真实代码中没有错误或写入错误。

标签: php xml xpath


【解决方案1】:

您的第二个表达式(循环内的 on)不依赖于上下文。位置路径开头的斜杠 (/) 表示绝对路径,它从文档节点开始。 [] 是过滤来自先前位置路径的结果的条件。它们本身就是完整的 Xpath 表达式。所以不,并不总是可以缩短 Xpath 表达式。但在您的情况下,您可以将公司节点作为列表获取,然后直接使用DOMXpath::evaluate() 获取详细信息。与DOMXpath::query() 不同,DOMXpath::evaluate() 可以返回节点列表或标量值。这取决于表达式。

$xml = <<<'XML'
<Seller>
  <Company>
    <Info> 
      <ID>123</ID>
      <Address>Some street, somewhere</Address>
    </Info>
    <Ref>
      <Who>456</Who>
      <Date>2017-01-05T01:59Z</Date>
    </Ref>
  </Company>
</Seller>
XML;

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);

foreach ($xpath->evaluate('/Seller/Company[Info/ID = "123"]') as $company) {
  var_dump(
    $xpath->evaluate('string(Info/ID)', $company),
    $xpath->evaluate('string(Ref/Date)', $company)
  );
}

输出:

string(3) "123"
string(17) "2017-01-05T01:59Z"

如果你只需要一个值,你可以直接获取它:

var_dump(
  $xpath->evaluate('string(/Seller/Company[Info/ID = "123"]/Ref/Date)')
);

【讨论】:

  • 做了很多工作,所以对此进行了测试,但它不起作用。它甚至没有回答我的问题。我的 XML 有超过 1 个 Ref 并且正确的日期在 who "456" 中。所以它应该类似于 ("Ref [Who = '456']/Date ")。但我的问题是它甚至没有进入 foreach 循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 2016-04-24
  • 2011-04-05
  • 1970-01-01
相关资源
最近更新 更多