复制XML节点,并对子节点添加了更改

时间:2013-11-23 14:41:10

标签: xml xslt copy

我有一个具体问题。我有XML,我需要转换,以便复制一个节点。

输入XML是:

<root>
    <book>
        <name>
        ... some data
        </name>
        <info>
        ... some data
        </info>
        <trees>
            <tag1></tag1>
            <tag2></tag2>
            <tag3></tag3>
            .... other tags
            <tag n+1></tag n+1> 
        </trees>
        .
        .
        .
        other nodes
        .
        .
        .
        .
        </book>
        <book>
        .
        .
        .
        </book>
</root>

现在我需要将节点“树”复制3次并像这样写,只需对子节点进行少量更改。输出XML需要像:

<root>
    <book>
        <name>
        ... some data
        </name>
        <info>
        ... some data
        </info>

        <trees>
            <tag1></tag1>
            <tag2></tag2>
            <tag3></tag3>
            .... other tags
            <tag n+1></tag n+1> 
        </trees>
        <treesA>
            <tag1A></tag1A>
            <tag2A></tag2A>
            <tag3A></tag3A>
            .... other tags
            <tag n+1></tag n+1> 
        </treesA>
        <treesA>
            <tag1B></tag1B>
            <tag2B></tag2B>
            <tag3B></tag3B>
            .... other tags
            <tag n+1></tag n+1> 
        </treesB>
        <treesC>
            <tag1C></tag1C>
            <tag2C></tag2C>
            <tag3C></tag3C>


    .... other tags
        <tag n+1></tag n+1> 
    </treesC>
    .
    .
    .
    other nodes
    .
    .
    .
    .
</book>
<book>
.
.
.
</book>

感谢您对我的问题的所有帮助。 Eoglasi

2 个答案:

答案 0 :(得分:1)

在XSLT 2.0中使用tunnel参数来保存后缀可以很好地完成这个:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

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

  <xsl:template match="*">
    <xsl:param name="suffix" tunnel="yes" select="''" />
    <xsl:element name="{name()}{$suffix}" namespace="{namespace-uri()}">
      <xsl:apply-templates select="@*|node()" />
    </xsl:element>
  </xsl:template>

  <xsl:template match="trees">
    <xsl:next-match />
    <xsl:next-match>
      <xsl:with-param name="suffix" tunnel="yes" select="'A'" />
    </xsl:next-match>
    <xsl:next-match>
      <xsl:with-param name="suffix" tunnel="yes" select="'B'" />
    </xsl:next-match>
    <xsl:next-match>
      <xsl:with-param name="suffix" tunnel="yes" select="'C'" />
    </xsl:next-match>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

使用

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

<xsl:template match="trees">
  <xsl:call-template name="identity"/>
  <xsl:apply-templates select="." mode="change">
    <xsl:with-param name="suffix" select="'A'"/>
  </xsl:apply-templates>
  <xsl:apply-templates select="." mode="change">
    <xsl:with-param name="suffix" select="'B'"/>
  </xsl:apply-templates>
  <xsl:apply-templates select="." mode="change">
    <xsl:with-param name="suffix" select="'C'"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="*" mode="change">
  <xsl:param name="suffix"/>
  <xsl:element name="{name()}{$suffix}" namespace="{namespace-uri()}">
    <xsl:apply-templates select="@* | node()" mode="change">
      <xsl:with-param name="suffix" select="$suffix"/>
    </xsl:apply-templates>
  </xsl:element>
</xsl:template>