Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT: If tag exists, apply template; if not, choose static value

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>

like image 202
Issa Fram Avatar asked Apr 26 '11 13:04

Issa Fram


People also ask

What does template match mean in XSLT?

XSLT <xsl:template> The match attribute is used to associate the template with an XML element. The match attribute can also be used to define a template for a whole branch of the XML document (i.e. match="/" defines the whole document).

Can we use contains in XSLT?

contains() Function — Determines if the first argument string contains the second.

What is current group () in XSLT?

Returns the contents of the current group selected by xsl:for-each-group. Available in XSLT 2.0 and later versions. Available in all Saxon editions. current-group() ➔ item()*

Which element allows you to do looping in XSLT?

The <xsl:for-each> element allows you to do looping in XSLT.


2 Answers

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.

like image 148
Martin Honnen Avatar answered Sep 29 '22 19:09

Martin Honnen


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.

like image 32
Dimitre Novatchev Avatar answered Sep 29 '22 19:09

Dimitre Novatchev