2017-04-03 64 views
0

我有一个相当深的嵌套xml结构,我想在选择节点后找到具有特定值的元素。在下面的示例中,我有一个'B'数组,并且在选择每个'B'节点后,我想要获取以“历史记录”开头的其中一个子节点(不一致)的文本XPath在节点选择中查找带有文本()的任何元素

<A> 
    <Items> 
     <B> 
      <C> 
       <D>history: pressed K,E</D> // could be nested anywhere 
      </C> 
     </B> 
     <B> 
      <C> 
       <E>history: pressed W</E> 
      </C> 
     </B> 
    </Items> 
</A> 


    // Select the nodes from the array (B) 
var nodes = select(xmldoc, "//A/Items/B"); 

    // Iterate through the nodes. 
nodes.forEach(node){ 

    // is it possible to select any element that starts with the text 'history' from the already selected node. 
var history = select(node, "???[starts-with(.,'history')]"); 

我看到的所有样本都是从// * [text()]开始,从结构的根部搜索。

回答

0
//B//*[starts-with(normalize-space(), 'history')] 

看起来像它会做你想要的。

它选择<B>的任何后代元素,其文本内容以'history'开头”

手动迭代寻找更多节点通常不是必需的。 XPath为您做到了这一点。如果由于其他原因必须进行迭代,请使用上下文节点.进行选择。

nodes.forEach(function (node) { 
    var history = select(node, "./*[starts-with(.,'history')]"); 
}); 

如果你实际上是在寻找“任何文本节点...”

//B//text()[starts-with(normalize-space(), 'history')] 

或者“有没有进一步的子元素的任何元素节点...”

//B//*[not(*) and starts-with(normalize-space(), 'history')] 
+0

不幸的是,这仍然返回2结果,而不是结果的se节点。这是因为我们从拥有多个记录的// B开始。 – Celica

+0

类似这样的工作: select(node,“C/*/[starts-with(normalize-space(。),'history')]”); 所以它会从元素中选择。 *在当前级别搜索所有的孩子,它不搜索孩子的孩子,这是有道理的。 我实际上正在寻找一种方法来完成当前节点的全部搜索和所有孩子。 – Celica