mikey
mikey

Reputation: 135

Inserting a new DITA body element

Looking to transform an XML file to a valid DTD topic. To do this I need to insert a body element as shown.

<topic>
<title>My Title</title>
==><body>
<para>Intro text goes here.</para>
  <section/>
  <section/>
==></body>
</topic>

Upvotes: -2

Views: 51

Answers (1)

Daniel Haley
Daniel Haley

Reputation: 52888

If you need to add a body element as a child of topic, add a template that matches topic and add the element there.

The only slightly tricky part is that you want the title outside of body, so you'll have to separate that from the rest of the children.

Here's an XSLT 3.0 example. (I also added an id attribute to topic and changed para to p so it would be valid.)

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" doctype-public="-//OASIS//DTD DITA Topic//EN" doctype-system="topic.dtd"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:mode on-no-match="shallow-copy"/>
    
    <xsl:template match="topic">
        <topic id="{generate-id()}">
            <xsl:apply-templates select="@*|title"/>
            <body>
                <xsl:apply-templates select="node() except title"/>
            </body>
        </topic>
    </xsl:template>
    
    <xsl:template match="para">
        <p>
            <xsl:apply-templates select="@*|node()"/>
        </p>
    </xsl:template>
    
</xsl:stylesheet>

If you can't use XSLT 3.0, here's a 1.0 version (without xsl:mode and except)...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" doctype-public="-//OASIS//DTD DITA Topic//EN" doctype-system="topic.dtd"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="topic">
        <topic id="{generate-id()}">
            <xsl:apply-templates select="@*|title"/>
            <body>
                <xsl:apply-templates select="node()[not(self::title)]"/>
            </body>
        </topic>
    </xsl:template>
    
    <xsl:template match="para">
        <p>
            <xsl:apply-templates select="@*|node()"/>
        </p>
    </xsl:template>
    
</xsl:stylesheet>

Fiddle: http://xsltfiddle.liberty-development.net/3Nzb5iZ

Upvotes: 1

Related Questions