I am new to XSLT in general so please bear with me...
With that in mind, what I am trying to do is check for a certain tag in the XML. If it is there I want to apply a template. If not, I want to add it (as a blank value). Basically always forcing it to be in the final output. How would I do this?
I had something like this...
<xsl:choose>
<xsl:when test="@href">
<xsl:apply-templates select="country" />
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
The top poriton of the code is what I think I have wrong. Need something in the otherwise
tag and my when
part is wrong i think.
<xsl:template match="country">
<xsl:if test=". != '' or count(./@*) != 0">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
Can anyone help? Thank you in advance.
EDIT:
Yes in the end i need at the very least a <country />
tag to be in the XML. But it is possible that it does not exist at all. If it doesn't exist, I have to put it in. An example good input would be <country>US</country>
In the template for the parent element the country element is expected to be in use e.g.
<xsl:template match="foo">
<xsl:if test="not(country)">
<country>US</country>
</xsl:if>
<xsl:apply-templates/>
</xsl:template>
Instead of foo
use the name of the parent element. And of course you could also do other stuff like copying the element, I have focused on the if
check. You do not really need an xsl:choose/when/otherwise
in my view, the xsl:if
should suffice as the apply-templates will not do anything with child elements that don't exist.
Even simpler:
<xsl:template match="foo[not(country)]">
<country>US</country>
<xsl:apply-templates/>
</xsl:template>
Do note:
No XSLT conditional instructions (such as <xsl:if>
) are used and they are not necessary.
Very often, the presence of <xsl:if>
or <xsl:choose>
is an indication that the code can be refactored and significantly improved by, among other things, getting rid of the conditional instructions.
You don't even need any kind of Conditional Processing. This stylesheet:
<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="item[not(country)]">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<country>Lilliput</country>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
With this input:
<root>
<item>
<country>Brobdingnag</country>
</item>
<item>
<test/>
</item>
</root>
Output:
<root>
<item>
<country>Brobdingnag</country>
</item>
<item>
<test></test>
<country>Lilliput</country>
</item>
</root>