【问题标题】:Copy XML node with added changes to child nodes将添加更改的 XML 节点复制到子节点
【发布时间】:2013-12-08 10:38:35
【问题描述】:

我有一个具体问题。我有需要转换的 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>

感谢您就我的问题提供的所有帮助。欧格拉西

【问题讨论】:

    标签: xml xslt copy


    【解决方案1】:

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

    <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>
    

    【讨论】:

    • 完美的 10 答案,谢谢。您能否告知一下这种转换是否使 XML 中的其他所有内容都与以前一样?
    • @eoglasi 差不多,唯一可能改变的是如果您在父元素上声明了命名空间但仅由其后代使用(在这种情况下,声明将沿着树向下移动到该点在哪里使用)。您的示例 XML 不包含任何命名空间,因此在您的情况下这应该不是问题,但如果是,您可以尝试在打开 &lt;xsl:element&gt; 标记后直接添加 &lt;xsl:copy-of select="namespace::*" /&gt;
    • 非常感谢您对此事的解释和帮助。欧格拉西
    【解决方案2】:

    使用

    <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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多