How can I use XSLT to create nodes if they don't exist? I need to insert the node <sectionhead> under <group>, but if the <group> node doesn't exist, then I need to create that as well.
eg.
Input (group node exists):
<story>
<group>
<overhead>
<l1>overhead</l1>
</overhead>
<headline>
<l1>headline</l1>
</headline>
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
Output:
<story>
<group>
<sectionhead />
<overhead>
<l1>overhead</l1>
</overhead>
<headline>
<l1>headline</l1>
</headline>
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
Input (group node does not exist):
<story>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
Output:
<story>
<group>
<sectionhead />
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
Try to translate the rules in your problem description directly into template rules:
"I need to insert the node <sectionhead>
under <group>
"
<xsl:template match="group">
<group>
<sectionhead/>
<xsl:apply-templates/>
</group>
</xsl:template>
"but if the <group>
node doesn't exist, then I need to create that as well."
<xsl:template match="story[not(group)]">
<story>
<group>
<sectionhead/>
</group>
<xsl:apply-templates/>
</story>
</xsl:template>
Here is a complete solution that overrides the identity rule/template for any story
element that has no group
child:
<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="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="story[not(group)]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<group>
<sectionhead />
</group>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="group[not(sectionhead)]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<sectionhead />
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
when it is applied on the provided XML document (with no group
):
<story>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
the wanted, correct result is produced:
<story>
<group>
<sectionhead/>
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
when applied to the first XML document (having group
that has no sectionhead
child):
<story>
<group>
<overhead>
<l1>overhead</l1>
</overhead>
<headline>
<l1>headline</l1>
</headline>
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
this same transformation again produces the wanted, correct result:
<story>
<group>
<sectionhead/>
<overhead>
<l1>overhead</l1>
</overhead>
<headline>
<l1>headline</l1>
</headline>
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With