带递归的XSLT复制节点

时间:2014-12-14 09:20:12

标签: xml xslt

我是XSLT的新手,我的XML文件具有以下结构:

<A>
  <label>
    <c>Tag number 1</c>
  </label>
  <row>
    <c>Tag Number 2</c>
  </row>
  <label>
    <c>Tag number 3</c>
  </label>
</A>

我想要的是将A标记分隔为:

<A>
  <label>
    <c>Tag number 1</c>
  </label>
  <row>
    <c>Tag number 2</c>
  <row>
</A>
<A>
  <label>
    <c>Tag number 3</c>
  </label>
</A>

所以我想要的是根据A标记分隔label标记,换句话说,复制label标记和所有后续标记,直到第二个label标记为止将被分隔为另一个A标记以及所有后续标记等等....

我希望我能清楚地描述它并原谅我的转储问题。

提前谢谢

1 个答案:

答案 0 :(得分:0)

考虑使用密钥按其前面第一个label元素查找非标签元素

<xsl:key name="label" match="*[not(self::label)]" use="generate-id(preceding-sibling::label[1])" />

然后,您可以选择所有label元素

开始
<xsl:template match="A">
   <xsl:apply-templates select="label" />
</xsl:template>

然后,在匹配label的模板中,您可以使用then键获取所有相关元素

<xsl:apply-templates select="key('label', generate-id())"/>

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="label" match="*[not(self::label)]" use="generate-id(preceding-sibling::label[1])" />

   <xsl:template match="@*|node()" name="identity">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="A">
      <xsl:apply-templates select="label" />
   </xsl:template>

   <xsl:template match="label">
      <A>
         <xsl:call-template name="identity" />
         <xsl:apply-templates select="key('label', generate-id())"/>
      </A>
   </xsl:template>
 </xsl:stylesheet>

注意我正在使用身份模板复制文档中的所有现有节点。