Reputation: 1091
i just wanted to check if any way to avoid verbose coding like below in xslt1.0, where we have multiple check conditions, the output elements to be copied based on certain conditions. If the condition is not true, then the element itself will be absent in the output. The reason I am asking, we have a lot of elements present in the xsl file.
My xslt
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<Root>
<xsl:if test="Root/a/text() = '1'">
<first>present</first>
</xsl:if>
<xsl:if test="Root/b/text() = '1'">
<second>present</second>
</xsl:if>
<xsl:if test="Root/c/text() = '1'">
<third>present</third>
</xsl:if>
<xsl:if test="Root/d/text() = '1'">
<fourth>present</fourth>
</xsl:if>
</Root>
</xsl:template>
</xsl:stylesheet>
my input xml
<Root>
<a>1</a>
<b>1</b>
<c>0</c>
<d>1</d>
</Root>
my output
<Root>
<first>present</first>
<second>present</second>
<fourth>present</fourth>
</Root>
Upvotes: 1
Views: 113
Reputation: 243459
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:ord>
<first>first</first>
<second>second</second>
<third>third</third>
<fourth>fourth</fourth>
</my:ord>
<xsl:variable name="vOrds" select="document('')/*/my:ord/*"/>
<xsl:template match="Root/*[. = 1]">
<xsl:variable name="vPos" select="position()"/>
<xsl:element name="{$vOrds[position()=$vPos]}">present</xsl:element>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<Root>
<a>1</a>
<b>1</b>
<c>0</c>
<d>1</d>
</Root>
the wanted, correct result is produced:
<Root>
<first>present</first>
<second>present</second>
<fourth>present</fourth>
</Root>
Upvotes: 2
Reputation: 163262
One way to do this would be to create a template for the output in output-template.xml:
<Root>
<first>present</first>
<second>present</second>
<third>present</third>
<fourth>present</fourth>
</Root>
and then process this:
<xsl:variable name="input" select="/"/>
<xsl:template match="Root/*">
<xsl:variable name="p" select="position()"/>
<xsl:if test="$input/Root/*[$p] = '1'">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
<xsl:template match="/">
<Root>
<xsl:apply-templates select="document('output-template.xml')/Root/*"/>
</Root>
</xsl:template>
Upvotes: 1