如何使用xpath(php)查询xml文件?

时间:2018-12-23 10:52:19

标签: php xml xpath phpquery

我正在尝试使用XPath查询XML文件。但是作为回报,我一无所获。我想我将查询的格式设置为false。

  

XML

<subject id="Tom">
   <relation unit="ITSupport" role="ITSupporter" />
  </subject>
  

PHP

$xpath = new DOMXpath($doc);
            $role = 'ITSupporter';
           $elements = $xpath-> query("//subject/@id[../relation/@role='".$role."']");              
           foreach ($elements as $element) {    
              $name = $element -> nodeValue;
              $arr[$i] = $name;
              $i = $i + 1;
           }    

如何获取ID TOM?我想将其保存到例如$ var

3 个答案:

答案 0 :(得分:1)

构建Xpath表达式:

  • 获取任何subject元素
    //subject
  • ...带有子元素relation
    //subject[relation]
  • ...具有带有给定文本的role属性
    //subject[relation/@role="ITSupporter"]
  • ...并获得@id的{​​{1}}属性
    subject

此外,可以清理源。 PHP数组可以使用//subject[relation/@role="ITSupporter"]/@id语法将新元素放入其中。

放在一起:

$array[]

输出:

$xml = <<<'XML'
<subject id="Tom">
  <relation unit="ITSupport" role="ITSupporter" />
</subject>
XML;

$role = 'ITSupporter';

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

$ids = [];
foreach ($xpath->evaluate("//subject[relation/@role='".$role."']/@id") as $idAttribute) {
  $ids[] = $idAttribute->value;
}
var_dump($ids);

如果只期望一个结果,则可以将其转换为Xpath:

array(1) { 
  [0]=> 
  string(3) "Tom" 
}

输出:

$id = $xpath->evaluate(
  "string(//subject[relation/@role='".$role."']/@id)"
);
var_dump($id);

XML命名空间

查看注释中发布的示例,您的XML使用没有前缀的名称空间string(3) "Tom" 。 XML解析器将解析它,因此您可以将节点读取为http://cpee.org/ns/organisation/1.0。以下是三个可以解决此问题的示例:

  • {http://cpee.org/ns/organisation/1.0}subject
  • <subject xmlns="http://cpee.org/ns/organisation/1.0"/>
  • <cpee:subject xmlns:cpee="http://cpee.org/ns/organisation/1.0"/>

Xpath表达式也必须这样做。但是Xpath没有 默认名称空间。您需要注册一个选择的使用前缀。这个 允许Xpath引擎将<c:subject xmlns:c="http://cpee.org/ns/organisation/1.0"/>解析为//org:subject

PHP不需要太多更改:

//{http://cpee.org/ns/organisation/1.0}subject

答案 1 :(得分:0)

尝试此XPath

//subject[relation/@role='".$role."']/@id

您将谓词应用于id属性,而不应用于subject元素。

答案 2 :(得分:-1)

通过id获取元素与通过$ role内容获取元素相同。 因此,如下所示; $xpath->query("//*[@id='$id']")->item(0); 换句话说,@ id应该放在'['括号中。