i have xml follows,
<doc> <a type="atr111"></a> <a type="atr111"></a> <a type="atr111"></a> <a type="atr222"></a> <a type="atr222"></a> <a type="atr222"></a> </doc> my requirements are,
- add dynamically increment
idattribute nodes has attributeatr111,atr222 - add new node inside nodes, named
<newnode>having attributeid="newattr"has attributeatr111,atr222 - change
<a>nodes attribute valueatr111atr222.
so expected output is,
<doc> <a id="id-1" type="atr222"><newnode id="newattr"/></a> <a id="id-2" type="atr222"><newnode id="newattr"/></a> <a id="id-3" type="atr222"><newnode id="newattr"/></a> <a id="id-4" type="atr222"><newnode id="newattr"/></a> <a id="id-5" type="atr222"><newnode id="newattr"/></a> <a id="id-6" type="atr222"><newnode id="newattr"/></a> </doc> the xsl have written output follows,
<xsl:template match="a" priority="1"> <!-- add new dynamic id --> <xsl:copy> <xsl:attribute name="id"> <xsl:value-of select="'id-'"/> <xsl:number count="a[@type='atr111' or @type='atr222']" level="any"/> </xsl:attribute> </xsl:copy> <!-- add newnode inside <a> node --> <xsl:copy> <newnode> <xsl:attribute name="id">newattr</xsl:attribute> </newnode> </xsl:copy> </xsl:template> <!-- change existing 'atr111' attribute value 'atr222' --> <xsl:template match="a/@type[. = 'atr111']"> <xsl:attribute name="type">atr222</xsl:attribute> </xsl:template> my current output comes follows,
<doc> <a id="id-1"/><a><newnode id="newattr"/></a> <a id="id-2"/><a><newnode id="newattr"/></a> <a id="id-3"/><a><newnode id="newattr"/></a> <a id="id-4"/><a><newnode id="newattr"/></a> <a id="id-5"/><a><newnode id="newattr"/></a> <a id="id-6"/><a><newnode id="newattr"/></a> </doc> as can see dynamic ids have added expected, , <newnode> new attribute has added.but has duplicated <a> node. existing attribute type has disappeared.
how can organize code expected output?
you forgot copy type attribute. <xsl:copy> copies current node itself, not children or attributes.
the following utilizes identity template process of copying children , attributes.
<xsl:transform xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output encoding="utf-8" indent="yes" /> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="a[@type='atr111' or @type='atr222']"> <xsl:copy> <xsl:attribute name="id"> <xsl:text>id-</xsl:text> <xsl:number count="a[@type='atr111' or @type='atr222']" level="any" /> </xsl:attribute> <xsl:apply-templates select="@*|node()" /> <newnode id="newattr" /> </xsl:copy> </xsl:template> </xsl:transform> output:
<doc> <a id="id-1" type="atr111"><newnode id="newattr"/></a> <a id="id-2" type="atr111"><newnode id="newattr"/></a> <a id="id-3" type="atr111"><newnode id="newattr"/></a> <a id="id-4" type="atr222"><newnode id="newattr"/></a> <a id="id-5" type="atr222"><newnode id="newattr"/></a> <a id="id-6" type="atr222"><newnode id="newattr"/></a> </doc> you of course use <xsl:copy-of select="@type" /> if there no other children, that's less flexible: copying through identity template enables carry on variable input , add, example, <xsl:template match="a/@type"> later-on special processing @type nodes, if necessary.
Comments
Post a Comment