Search code examples
xmlxsltdocbookdita

Section element have to close after the para element using XSLT


While doing docbook to dita process using oxygen, I need to change some.

My Input xml file is:

<section><title>DESCRIPTION</title>
<para>The A380 is available with two types of turbofan engines, the
Rolls-Royce Trent 900 (variants A380-841, −842 and −843F) or the Engine
Alliance GP7000 (A380-861 and −863F).  Noise reduction was an important
requirement in the A380 design, and particularly affects engine design.</para>
<section><title>Wing Landing Gear</title>
<section><para>Each wing landing gear has a leg assembly and
a four-wheel bogie beam. The WLG leg includes a Bogie Trim Actuator
(BTA) and an oleo-pneumatic shock absorber.</para>
</section></section><section><title>Body Landing Gear</title>
<section><para>The two body landing gears have a six-wheel bogie
beam and a leg assembly that includes an oleo- pneumatic shock absorber.
A two-piece drag-stay assembly mechanically locks the leg in the extended
position.</para>
</section></section></section>

XSL(2.0) used as:

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

<xsl:template match="section">
        <section>       
            <xsl:apply-templates select="node()[not(self::section)]"/>
        </section>
<xsl:apply-templates select="section"/> 
    </xsl:template>   

<xsl:template match="section/section[para]">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="para">
  <p>
    <xsl:apply-templates/>
  </p>
</xsl:template>

Output which I'm getting is:

<section>
         <title>DESCRIPTION</title>
         <p>The A380 is available with two types of turbofan engines, the
Rolls-Royce Trent 900 (variants A380-841, −842 and −843F) or the Engine
Alliance GP7000 (A380-861 and −863F).  Noise reduction was an important
requirement in the A380 design, and particularly affects engine design.</p>
         </section>
      <section>
         <title>Wing Landing Gear</title>
      </section>
      <p>Each wing landing gear has a leg assembly and
a four-wheel bogie beam. The WLG leg includes a Bogie Trim Actuator
(BTA) and an oleo-pneumatic shock absorber.</p>
      <section>
         <title>Body Landing Gear</title>
      </section>
      <p>The two body landing gears have a six-wheel bogie
beam and a leg assembly that includes an oleo- pneumatic shock absorber.
A two-piece drag-stay assembly mechanically locks the leg in the extended
position.</p>

Expected output xml needs to be:

<section>
         <title>DESCRIPTION</title>
         <p>The A380 is available with two types of turbofan engines, the
Rolls-Royce Trent 900 (variants A380-841, −842 and −843F) or the Engine
Alliance GP7000 (A380-861 and −863F).  Noise reduction was an important
requirement in the A380 design, and particularly affects engine design.</p>
         </section>
      <section>
         <title>Wing Landing Gear</title>
          <p>Each wing landing gear has a leg assembly and
a four-wheel bogie beam. The WLG leg includes a Bogie Trim Actuator
(BTA) and an oleo-pneumatic shock absorber.</p></section>
      <section>
         <title>Body Landing Gear</title>
        <p>The two body landing gears have a six-wheel bogie
beam and a leg assembly that includes an oleo- pneumatic shock absorber.
A two-piece drag-stay assembly mechanically locks the leg in the extended
position.</p></section>

Please see the code and guide on me. Thanks in advance


Solution

  • I think it is the case of replace the template matching Section, which is currently matching too much, with one that targets only one without nested sections...

    <xsl:template match="section[not(section/para)]">
    

    Try this XSLT

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" />
    
    <xsl:template match="*|text()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="section[not(section/para)]">
        <section>       
            <xsl:apply-templates select="node()[not(self::section)]"/>
        </section>
        <xsl:apply-templates select="section"/> 
    </xsl:template>
    
    <xsl:template match="section/section[para]">
        <xsl:apply-templates/>
    </xsl:template>
    
    <xsl:template match="para">
      <p>
        <xsl:apply-templates/>
      </p>
    </xsl:template>
    </xsl:stylesheet>