I'm creating an XSLT where I want to get values from XML elements. If they do not exist, I want to ensure some default value is inserted. I tried making this work with XSL:template match, which works great, and then return a value if the element does not exist with
xsl:template match="a/b/[not(c)]
This adds the default value, but then removes all other values.
I tried using xsl:apply-templates
on top of this, to add all the existing objects' values too. This works, but only for a single [not(object)]
clause. I.e., if there are multiple non-existing objects that are matched, only the last one is displayed along with all the matched objects.
How can I ensure I get all "default" values (or: values for non-existing objects) while also obtaining all the existing elements?
Here's a simplified version of my current XSLT:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<items>
<xsl:apply-templates select="LinkedHashMap"/>
</items>
</xsl:template>
<xsl:template match="A/items/itemA">
<first>
<xsl:value-of select="."/>
</first>
</xsl:template>
<xsl:template match="A/items[not(itemA)]">
<first>
"Default value"
</first>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="A/items/itemB">
<second>
<xsl:value-of select="."/>
</second>
</xsl:template>
<xsl:template match="A/items[not(itemB)]">
<second>
"Default value"
</second>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="A/items/itemC">
<third>
<xsl:value-of select="."/>
</third>
</xsl:template>
<xsl:template match="A/items[not(itemC)]">
<third>
"Default value"
</third>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="A/items/itemD">
<third>
<xsl:value-of select="."/>
</third>
</xsl:template>
<xsl:template match="A/items[not(itemD)]">
<fourth>
"Default value"
</fourth>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
Input:
<LinkedHashMap>
<A>
<items>
<itemA>First item</itemA>
<itemB>Second item</itemB>
</items>
</A>
</LinkedHashMap>
Results in :
<?xml version="1.0" encoding="UTF-8"?>
<items>
<fourth>
"Default value"
</fourth>
<first>First item</first>
<second>Second item</second>
</items>
Where I also expect to find a
<third>"default value"</third>
How can I ensure all default values are added here? Thanks!
CodePudding user response:
<xsl:template match="node()">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="items">
<xsl:copy>
<xsl:choose>
<xsl:when test="itemA">
<xsl:apply-templates select="itemA"/>
</xsl:when>
<xsl:otherwise>
<first>
"Default value"
</first>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="itemB">
<xsl:apply-templates select="itemB"/>
</xsl:when>
<xsl:otherwise>
<second>
"Default value"
</second>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="itemC">
<xsl:apply-templates select="itemC"/>
</xsl:when>
<xsl:otherwise>
<third>
"Default value"
</third>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="itemD">
<xsl:apply-templates select="itemD"/>
</xsl:when>
<xsl:otherwise>
<forth>
"Default value"
</forth>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
<xsl:template match="itemA">
<first>
<xsl:value-of select="."/>
</first>
</xsl:template>
<xsl:template match="itemB">
<second>
<xsl:value-of select="."/>
</second>
</xsl:template>
<xsl:template match="itemC">
<third>
<xsl:value-of select="."/>
</third>
</xsl:template>
<xsl:template match="itemD">
<third>
<xsl:value-of select="."/>
</third>
</xsl:template>