xml - moving repeating elements into a copy of its parent -
if <animal>
has more 1 <xxx>
need duplicate <animal>
(duplicate count = count of repeating <xxx>
within corresponding<animal>
) , move repeating <xxx>
copy.
in xml <xxx>
repeating twice first instance of <animal>
, in output need have 2 <animals>
. first <animal>
should contain first instance of <xxx>
, second <animal>
should contain second instance of <xxx>
input xml
<?xml version="1.0" encoding="utf-8"?> <header> <animal> <element1>element1</element1> <element2>element2</element2> <element3 lang="en">element3</element3> <xxx> <code>yy</code> <description>code yy</description> </xxx> <xxx> <code>zz</code> <description>code zz</description> </xxx> </animal> <animal> <xxx> <code>aa</code> <description>code aa</description> </xxx> </animal> </header>
required required transformation
<?xml version="1.0" encoding="utf-8"?> <header> <animal> <element1>element1</element1> <element2>element2</element2> <element3 lang="en">element3</element3> <xxx> <code>yy</code> <description>code yy</description> </xxx> </animal> <animal> <element1>element1</element1> <element2>element2</element2> <element3 lang="en">element3</element3> <xxx> <code>zz</code> <description>code zz</description> </xxx> </animal> <animal> <xxx> <code>aa</code> <description>code aa</description> </xxx> </animal> </header>
any appriciated. in advance
my solutions typically not elegant, produce desired output - have look...
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" > <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="*|@*"> <xsl:copy> <xsl:apply-templates select="*|@*|text()"/> </xsl:copy> </xsl:template> <xsl:template match="animal"> <xsl:param name="i" select="xxx[1]"/> <xsl:variable name="thisanimal" select="."/> <xsl:choose> <xsl:when test="count(xxx) = 1"> <!-- 1 here --> <xsl:copy-of select="."/> </xsl:when> <xsl:when test="$i = xxx[1]"> <!-- more 1 here, use first --> <xsl:copy> <xsl:apply-templates select="*[name() != 'xxx']"/> <xsl:apply-templates select="$i"/> </xsl:copy> <xsl:for-each select="xxx[position() > 1]"> <xsl:apply-templates select="$thisanimal"> <xsl:with-param name="i" select="."/> </xsl:apply-templates> </xsl:for-each> </xsl:when> <xsl:otherwise> <!-- more 1 here --> <xsl:copy> <xsl:apply-templates select="*[name() != 'xxx']"/> <xsl:apply-templates select="$i"/> </xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:transform>
Comments
Post a Comment