Copy node and add value to attribute with Xslt

匿名 (未验证) 提交于 2019-12-03 08:54:24

问题:

Basiccly i have problem with xml and xslt which i do not know how to solve, and would appreciate any help regarding this matter where to start. I have 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>

Now i would now need to copy, all nodes in "test" node in this way and add always value 3 to settings value (settings value is changing in test node) in 4 new nodes like shown below so i would get:

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

Thanks a lot for any help regarding this matter, eoglasi

回答1:

As mentioned in the comments, the identity transform is what you need when you are transforming XML and only want to make changes to certain parts of the XML

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

You say you want to "add always value 3 to settings", so you would have a template that matches the settings attribute.

<xsl:template match="test/@setting">

(In this case, it will only match the settings attribute that belongs to a test element.)

And then within this template you then use xsl:attribute to output a new attribute instead with the same name but amended value

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

You say you also want to copy 4 nodes under the test node. This means you need a template to match the test node as that is what you need to transform to add the children

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

It is not clear where the data for your new nodes comes from, so you will have to do that yourself, but it does look like the setting attribute comes from the setting attribute on the test element. Therefore, your code may look like this:

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

Note the use of Attribute Value Templates here. The curly braces { } indicate an expression to be evaluated rather than output literally.

Try this XSLT as a sample.

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!