选择位于相同位置的不同父母的元素

时间:2015-09-27 14:25:20

标签: xml xpath

说我有以下XML代码段

<line>
  <data>
    <p>5<p/>
    <p>40<p/>
    <p>30<p/>
    <p>25<p/>
  </data>
  <attData>
     <att>
     </att>
     <att>
       <type>
         <n/>
         <value>no use</value>    
       </type>
     </att>
     <att>
       <type>
         <n/>
         <value>use</value>    
       </type>
     </att>
     <att>
       <type>
         <n/>
         <value>no use</value>    
       </type>
     </att>
  </attData>
</line>

xml文档中有许多元素,它们具有相同名称和顺序的子元素,因此对于每个元素,后代 p的数量元素始终等于后代 att 元素的数量。所以有一致的模式重复 有没有办法将 p 元素与其父元素的相应文档顺序匹配到 att 元素?
我正在尝试设计一个xpath表达式,只选择 p 元素,这些元素没有相应的等于&#39; no use&# 39;
所以上面的xml会输出:

     5  
     30  

我试图避免在position()中使用变量,因为我需要将表达式用于排序选择 我有:

 <xsl:for-each select="*/line/attData/att[not(type[value='no use'])]">

选择所需的 att 元素
并从中:

  <xsl:value-of select= "count(preceding-sibling::*)+1"/>

attData 提供 att 的文档顺序,但我无法弄清楚如何匹配此顺序并选择所需的 p < / em>元素。 任何帮助将非常感谢,我对此很新。
我正在使用XSLT 1.0

1 个答案:

答案 0 :(得分:0)

您可以定义一个键

<xsl:key name="pos" match="line/data/p" use="concat(generate-id(../..), '|', count(preceding-sibling::p))"/>

然后在你的代码中你可以使用

<xsl:template match="line/attData/att[not(type[value='no use'])]">
  <xsl:apply-templates select="key('pos', concat(generate-id(../..), '|', count(preceding-sibling::att)))"/>
</xsl:template>

处理相应的att元素。或者排序可能

<xsl:for-each select="*/line/attData/att[not(type[value='no use'])]">
  <xsl:sort select="key('pos', concat(generate-id(../..), '|', count(preceding-sibling::att)))" data-type="number"/>
</xsl:for-each>