使用 DOMDocument,是否可以根据附加参数过滤 getElementsByTagName 的输出?

With DOMDocument, is it possible to filter the output of getElementsByTagName based on an additional parameter?

拿这个xml举例如下:

<xml>
<siblings>
    <brother>Derek</brother>
    <sister>Elaine</sister> 
    <sister>Flora</sister>
</siblings>
<siblings>
    <brother>Gary</brother>
    <sister>Hannah</sister> 
</siblings> 
</xml>

如果我使用下面的代码:

$xmlDoc=new DOMDocument();
$xmlDoc->load("Family.xml");
$siblings = $xmlDoc->getElementsByTagName('Siblings');
$sister = $xmlDoc->getElementsByTagName('Sister');  

这通常会 return 标记 "Sister" 的所有实例,在本例中为 "Elaine"、"Flora" 和 "Hannah"。是否可以更改它以便您可以按其他节点之一的名称过滤标记名?例如,使用名称 "Derek" 将输出更改为仅 "Elaine" 和 "Flora"。

Xpath 表达式允许您使用条件从 DOM.

中获取节点
$xml = <<<'XML'
<xml>
<siblings>
    <brother>Derek</brother>
    <sister>Elaine</sister> 
    <sister>Flora</sister>
</siblings>
<siblings>
    <brother>Gary</brother>
    <sister>Hannah</sister> 
</siblings> 
</xml>
XML;

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

$expression = '/xml/siblings[brother = "Derek"]/*[not(self::brother = "Derek")]';

foreach ($xpath->evaluate($expression) as $sibling) {
  echo $sibling->textContent, "\n";
}

输出:

Elaine
Flora

Xpath 表达式

  • 获取 siblings 个元素 ...
    /xml/siblings
  • ...如果他们有一个子元素brother,值为Derek ...
    /xml/siblings[brother = "Derek"]
  • ...并获取它们的子元素...
    /xml/siblings[brother = "Derek"]/*
  • ...如果它们不是值为 Derekbrother 元素节点。
    /xml/siblings[brother = "Derek"]/*[not(self::brother = "Derek")]