如何使用XSL选择两个元素之间的所有文本节点?

时间:2010-04-22 21:58:20

标签: xml xslt-2.0 xslt

我希望获得节点generate-id(.)之后和节点<m/>之前的所有文本节点的</n>。我正在寻找一些通用的XSL,而不是紧密耦合到下面提到的示例输入模式。对于任何输入模式,我想获取节点<m/><n/>之间所有文本节点的ID。

示例输入以便更好地理解:

<a>
  <b> 
    <c>
      This is first text node
    </c> 
  </b> 
  <d> 
    <e>
      This is my second text node
    </e> 
    <f> 
      This is my <m/>third text node 
    </f> 
    <g>
      One more text node
    </g>
  <h>
    <i>
      This is my fourth text node
    </i>
  </h>
  <j> 
    This is my fifth <n/>text node 
  </j>
  <k> 
    <l>
      This is my sixth text node 
    </l>
  </k>     
</d> 
</a> 

预期产量: 生成文本节点的id,其值为“第三文本节点”,“另一个文本节点”,“这是我的第四个文本节点”,“这是我的第五个”,位于节点<m/>和{{1}之间}

请提出您的想法。

1 个答案:

答案 0 :(得分:4)

此转化

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vtextPostM" select="//text()[preceding::m]"/>
 <xsl:variable name="vtextPreN" select="//text()[following::n]"/>

 <xsl:variable name="vtextBN-MandN" select=
  "$vtextPostM[count(.|$vtextPreN) = count($vtextPreN)]"/>

 <xsl:variable name="vNL" select="'&#xA;'"/>
 <xsl:variable name="vQ">"</xsl:variable>

 <xsl:template match="/">
   <xsl:for-each select="$vtextBN-MandN">
    <xsl:value-of select=
     "concat($vNL, 'Id: ', $vQ, generate-id(), $vQ,
            'Text: ', $vQ, ., $vQ)
     "/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时,会生成正确且需要的结果

Id: "IDAOZDLB"Text: "third text node
    "
Id: "IDAQZDLBIDAQZDLB"Text: "
      One more text node
    "
Id: "IDAUZDLBIDAUZDLB"Text: "
      This is my fourth text node
    "
Id: "IDAYZDLB"Text: "
    This is my fifth "

请注意使用节点集交集的Kaysian方法:

$ns1[count(.|$ns2)=count($ns2)]

选择属于节点集$ns1和节点集$ns2的所有节点。