用于更改现有xml标记并添加新xml标记的XSL代码

时间:2018-04-01 19:29:25

标签: xml xslt

我有以下示例XML文件,其中包含1,000个标记。

<AAA>
 <BBB>
  <CCC>
   <DDD>
    <EEE>
     <1>abc</1>
     <2>abc</2>
     <3>abc</3>
     <4>abc</4>
    </EEE>
   </DDD>
  </CCC>
 </BBB>
</AAA>

我需要将其转换为以下内容(使用两个子标记添加标记5并更新标记1)。

<AAA>
 <BBB>
  <CCC>
   <DDD>
    <EEE>
     <1>kkkkkkkk</1>
     <2>abc</2>
     <3>abc</3>
     <4>abc</4>
     <5>
        <a>abc</a>
        <b>abc</b>
     </5>
    </EEE>
   </DDD>
  </CCC>
 </BBB>
</AAA>

我根本无法做到这两件事,即我可以更新标签1或添加标签5.我需要能够做到这两点。我使用以下xsl转换来添加标记5.

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

 <xsl:template match="e:AAA/e:BBB/e:CCC/e:DDD/e:EEE">   
    <xsl:copy>              
     <xsl:copy-of select="*"/>
      <5>
        <a>abc</a>
        <b>abc</b>
      </5>
    </xsl:copy>     
</xsl:template>

无论我尝试什么,我都无法更新标签1 - select =“*”的副本似乎覆盖了它。 关于如何实现更新和添加的任何想法都非常赞赏。

1 个答案:

答案 0 :(得分:1)

简单, - 只需从您的副本中排除<1>(XML名称不能合法地以数字开头,所以我将其称为<tag1><tag5>):< / p>

<xsl:template match="e:AAA/e:BBB/e:CCC/e:DDD/e:EEE">   
  <xsl:copy>
    <tag1>kkkkkkkkkk</tag1>
    <xsl:copy-of select="*[not(self::tag1)]"/>
    <tag5>
      <a>abc</a>
      <b>abc</b>
    </tag5>
  </xsl:copy>
</xsl:template>

上面只有当你想要替换第一个元素并在最后添加一个新元素时才能正常工作,在所有其他情况下它会混淆元素顺序。

假设您要替换<tag2>,使用与<xsl:apply-templates>匹配的模板会更好,因为它会保留输入元素顺序:

<xsl:template match="e:AAA/e:BBB/e:CCC/e:DDD/e:EEE">   
  <xsl:copy>
    <xsl:apply-templates select="*" />
    <tag5>
      <a>abc</a>
      <b>abc</b>
    </tag5>
  </xsl:copy>     
</xsl:template>

<xsl:template match="tag2">
    <xsl:copy>zzzzzzzzzz</xsl:copy>
</xsl:template>

使用<xsl:apply-templates>的方法比使用<xsl:copy-of>的方法更灵活:要在<tag3>之后插入新元素,您可以使用以下模板:

<xsl:template match="tag3">
    <xsl:copy-of select="." />
    <tag3-1>zzzzzzzzzz</tag3-1>
</xsl:template>