复制节点并使用Xslt向属性添加值

eog*_*asi 4 xslt copy add nodes

Basiccly我有xml和xslt的问题,我不知道如何解决,并希望任何有关此问题的帮助从哪里开始.我有XML:

<root>
 <test value="1" setting="3">
   <tag1>data....</tag1>
   <tag2>data....</tag2>
   <tag n+1>data....</tag n+1>
 </test>
 <test value ...
 .
 .
 .
 </test>
</root>
Run Code Online (Sandbox Code Playgroud)

现在,我现在需要以这种方式复制"test"节点中的所有节点,并在4个新节点中将值3总是添加到设置值(设置值在测试节点中正在变化),如下所示,所以我会得到:

<root>
 <test value="2" setting="6">
   <ni1 name="1" setting1="6">data....</ni1>
   <ni2 name="1" setting1="6">data....</ni2>
   <ni3 name="1" setting1="6">data....</ni3>
   <ni4 name="1" setting1="6">data....</ni4>
   <tag1>data....</tag1>
   <tag2>data....</tag2>
   <tag n+1>data....</tag n+1>
 </test>
 <test value ...
 .
 .
 .
 </test>
</root>
Run Code Online (Sandbox Code Playgroud)

非常感谢你对此事的任何帮助,eoglasi

Tim*_*m C 11

正如评论中所提到的,身份转换是您在转换XML时所需要的,并且只想对XML的某些部分进行更改

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

您说您想"始终将值3添加到设置",因此您将拥有与settings属性匹配的模板.

<xsl:template match="test/@setting">
Run Code Online (Sandbox Code Playgroud)

(在这种情况下,它只匹配属于测试元素的settings属性.)

然后在此模板中,您可以使用xsl:attribute输出一个新属性,而不是使用相同的名称但修改值

<xsl:attribute name="setting">
  <xsl:value-of select="number(.) + 3" />
</xsl:attribute>
Run Code Online (Sandbox Code Playgroud)

您说您还想在测试节点下复制4个节点.这意味着您需要一个模板来匹配测试节点,因为您需要转换以添加子节点

<xsl:template match="test">
   <xsl:copy>
     <xsl:apply-templates select="@*" />
     <!-- Add new nodes here -->
     <xsl:apply-templates select="node()"/>
   </xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

目前尚不清楚新节点的数据来自哪里,因此您必须自己做,但看起来设置属性来自test元素的setting属性.因此,您的代码可能如下所示:

<ni1 name="1" setting1="{number(@setting) + 3}">data....</ni1>
Run Code Online (Sandbox Code Playgroud)

请注意此处使用属性值模板.花括号{ }表示要计算的表达式而不是字面输出.

试试这个XSLT作为样本.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="test/@setting">
    <xsl:attribute name="setting">
      <xsl:value-of select="number(.) + 3" />
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="test">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <ni1 name="1" setting1="{number(@setting) + 3}">data....</ni1>
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)