XPath获取一级子节点

6

使用DOMXPath::query,是否可以仅获取一层深度的childNodes?

例如,如果我有一个文档如下:

<div>
    <span>
        <cite>
        </cite>
    </span>
    <span>
        <cite>
        </cite>
    </span>
</div>

我希望NodeList只包含span元素,而不是cite元素。

需要注意的是,这些元素并不总是相同的(例如div,span等)。 我需要它能够适用于任何类型的元素。

这是我尝试过但似乎没有起作用的方法:

//*[not(ancestor::div)]
2个回答

3
如果您使用

/div/*

然后,您将获得此元素中所有直接子项的列表,但这些子项包含它们自己的子项。我认为您无法删除子项的子项。
使用默认轴,称为child ::。此轴仅返回当前节点下1级的元素。 * 匹配所有元素,但不包括属性或text()。
您必须指定到达您的节点的路径,并小心使用//node,因为它表示descendant :: node并返回此树中该名称的所有节点。

感谢child::axis的建议。这应该是被接受的答案。 - Eternal21

2

您的问题有点不够明确,因此有几种解释方式。如果您想获取当前元素的所有直接子元素(以及它们的所有子元素),则使用:

*/*

对于您的例子,这将为您提供
<span>
    <cite>
    </cite>
</span>

并且

<span>
    <cite>
    </cite>
</span>

如果您想获取所有子节点,那么请使用node()而不是*

*/node()

对于你的示例,这将给你上面的两个子元素以及换行/缩进text()节点。
然而,如果你只想要子节点而不是它们的子节点(即仅span元素,但不包括其子元素),你必须使用两个表达式:
1.通过*/*选择直接子元素 2.处理这些子元素并仅选择文本节点而不是孙元素,使用text() 我的PHP有点生疏,但应该像这样工作:
$doc = new DOMDocument;
// set up $doc
$xpath = new DOMXPath($doc);

// perform step #1
$childElements = $xpath->query('*/*');

$directChildren = array();
foreach ($childElements as $child) {
  // perform step #2
  $textChildren = $xpath->query('text()', $child);
  foreach ($textChildren as $text) {
    $directChildren[] = $text;
  }
}
// now, $directChildren contains all text nodes

谢谢nd,最后一个就是我要找的。只需要直接子节点,没有孙子节点。你能多解释一下那个例子吗?我对XPath非常陌生,还没完全懂。 - Greg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接