使用xpath在php上获取特定的xml数据

时间:2016-01-26 09:52:07

标签: php xml parsing dom xpath

我有像这样的xml响应;

<n:Crev xmlns:soap="http://a.com"
                    xmlns:obj="http://b.com"
                    xmlns:n="http://c.com"
                    xmlns:msg="http://d.com"
                    xmlns="http://e.com"
                    xmlns:xsi="http://f.com"
                    xsi:schemaLocation="http://g.com">
  <n:Header>
  <msg:mydata>123123</msg:mydata>
  </n:Header>
</n:Crev>

现在我想得到&#39; msg:mydata &#39;价值..

我尝试了一些xpath但他们没有工作并尝试在线xpath创建者它给出了类似的东西;

'/n:Crev[@xmlns:soap="http://a.com"]/n:Header/msg:mydata/text()'

但它也没有工作..所以我怎么能为此写xpath? 感谢

2 个答案:

答案 0 :(得分:2)

我成功完成了以下代码:

<?php
$xmlStr = '<n:Crev xmlns:soap="http://a.com"
                    xmlns:obj="http://b.com"
                    xmlns:n="http://c.com"
                    xmlns:msg="http://d.com"
                    xmlns="http://e.com"
                    xmlns:xsi="http://f.com"
                    xsi:schemaLocation="http://g.com">
  <n:Header>
  <msg:mydata>123123</msg:mydata>
  </n:Header>
</n:Crev>';

$xmlDoc = new DOMDocument();
$xmlDoc->loadXML($xmlStr);
$xmlPath = new DOMXPath($xmlDoc);
var_dump($xmlPath->query('//n:Crev/n:Header/msg:mydata')->item(0)->textContent);

结果:

string '123123' (length=6)

答案 1 :(得分:1)

nmsg是名称空间前缀。实际名称空间是xmlns属性的值。 XML解析器将解析命名空间。

这是一个小例子:

$document = new DOMDocument();
$document->loadXml('<n:Crev xmlns:n="http://c.com"/>');
var_dump(
  $document->documentElement->namespaceURI,
  $document->documentElement->localName
);

输出:

string(12) "http://c.com"
string(4) "Crev"

以下XML都具有相同的输出:

  • <n:Crev xmlns:n="http://c.com"/>
  • <Crev xmlns="http://c.com"/>
  • <c:Crev xmlns:c="http://c.com"/>

您可以将节点读作{http://c.com}Crev

要从DOM中获取节点或标量值,您可以使用Xpath :: evaluate()。但是要匹配名称空间,您必须为Xpath表达式注册前缀。这允许Xpath引擎解析命名空间并将它们与节点属性进行匹配。前缀不必与文档中的前缀相同。

$xml = <<<'XML'
<n:Crev xmlns:n="http://c.com" xmlns:msg="http://d.com">
  <n:Header>
    <msg:mydata>123123</msg:mydata>
  </n:Header>
</n:Crev>
XML;

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('c', 'http://c.com');
$xpath->registerNamespace('msg', 'http://d.com');

var_dump(
  $xpath->evaluate('string(/c:Crev/c:Header/msg:mydata)')
);

输出:

string(6) "123123"

如果表达式是/c:Crev/c:Header/msg:mydata之类的位置路径,则结果为DOMNodeList,但Xpath函数或运算符可以返回标量值。