Tcanarchy
Tcanarchy

Reputation: 770

XSLT: Add content to an XML depending on conditions

I am trying to transform an XML-file to another XML-file, with extra content added in case something is not provided.

My XML looks like this:

<bookstore>
   <book>
        <title>Book1</title>
        <author>Author1</author>
        <chapters>
             <chapter>
                  <ch-name>BLABLA</ch-name>
                  <ch-number>1</ch-number>
             </chapter>
        </chapters>
   </book>
   <book>
        <title>Book2</title>
        <author>Author2</author>
        <chapters>
             <chapter>
                  <ch-name>Test</ch-name>
                  <ch-number>1</ch-number>
             </chapter>
        </chapters>
   </book>
   <book>
        <title>Book3</title>
        <author>Author3</author>
   </book>
</bookstore>

Now, I want to add the chapters element (and its child elements) to the books, where it doesn't exist already, to create some sort of default.

My XSLT looks like this:

<dns:template match="book[not(exists(chapters))]">
    <xsl:copy>
      <xsl:apply-templates select="@*|*"/>
    </xsl:copy>
    <chapters>
           <chapter>
                <ch-name>default</ch-name>
                <ch-number>default</ch-number>
            </chapter>
    </chapters>   
</dns:template>

<xsl:template match="@* | *">
    <xsl:copy>
        <xsl:apply-templates select="@* | * | text()"/>
    </xsl:copy>
</xsl:template>

However, when I try this in an online editor, there are no changes. The dns namespace should support the not(exists) part.

Is there something wrong with my XSLT?

Thank you for any help given!

Upvotes: 0

Views: 62

Answers (1)

Linga Murthy C S
Linga Murthy C S

Reputation: 5432

Change the "dns" prefix to "xsl"(of course you can have the prefix defined again with the same namespace, but not recommended). If you are using XSLT1.0, there is no "exists()" function present. Also, "chapters" needs to be inside . You can use this xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="book[not(chapters)]">
    <xsl:copy>
        <xsl:apply-templates select="@*|*"/>
        <chapters>
            <chapter>
                <ch-name>default</ch-name>
                <ch-number>default</ch-number>
            </chapter>
        </chapters>
    </xsl:copy>

</xsl:template>

<xsl:template match="@* | *">
    <xsl:copy>
        <xsl:apply-templates select="@* | * | text()"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

Upvotes: 2

Related Questions