Search code examples
xmlxsltxslt-2.0

Need to change the ID for different topics


I'm having one h1 section header and their corresponding para's (para,list) and lot of h2 section header and their corresponding para's (para,list). I want to change the each h1 and h2 as topic with different ID's

XML Input as:

<?xml version="1.0"?>
<ImportArticle>
    <Segments>
        <Segment>
            <Body>
                <h1>Essay on Education</h1>
                <h2>Importance of Education Essay</h2>
                <p>Following are different types of essay topics</p>
                <h2>Essay on Music</h2>
                <p>Education is the systematic process of improving learning</p>
                <ul>
                    <li>
                        <p>
                        <b>Find understandable essay.</b> Education essay is the most important</p>
                    </li>
                    <li>
                        <p>
                        <b>Education is the act.</b> It helps us to easily understand and deal with any problem.</p>
                    </li>
                </ul>
                <p>It improves our knowledge, skill, confidence level and personality.</p>
            </Body>
        </Segment>
    </Segments>
</ImportArticle>

XSL I Used as:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output
    method="xml"
    indent="yes"
    omit-xml-declaration="no"
    doctype-public="urn:pubid:com.doctype.doctypes:doctypes:dita:topic"
    doctype-system="topic.dtd"/>

<xsl:strip-space elements="*"/>

  <xsl:template match="ImportArticle">
    <xsl:processing-instruction name="xml-stylesheet">type="text/xsl" href="dita.xsl"</xsl:processing-instruction>
    <xsl:apply-templates/>
   </xsl:template>

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

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

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

  <xsl:template match="h1">
<topic id="topic_1">
    <title>
 <xsl:apply-templates/>
    </title>
</topic>
  </xsl:template>

  <xsl:template match="h2">
    <topic id="topic_2">
      <title>
 <xsl:apply-templates/>
      </title>
    </topic>
  </xsl:template>

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

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

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

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

</xsl:stylesheet>

Output I'm getting as:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="DITA.xsl"?>
<!DOCTYPE topic
  PUBLIC "urn:pubid:com.doctypes.doctypes:doctypes:dita:topic" "topic.dtd">
<topic id="topic_1">
<title>Essay on Education</title>
</topic>
<topic id="topic_2">
<title>Importance of Education Essay</title>
</topic>
<p>Following are different types of essay topics</p>
<topic id="topic_2">
<title>Essay on Music</title>
</topic>
<p>Education is the systematic process of improving learning</p>
<ul>
<li><p><b>Find understandable essay.</b> Education essay is the most important</p></li>
<li><p><b>Education is the act.</b> It helps us to easily understand and deal with any problem.</p></li>
</ul>
<p>It improves our knowledge, skill, confidence level and personality.</p>

But I'm expecting output as "h1" topic needs to close after all the "h2" closes and each "h2" needs come in different id and para and list are come as per the input places:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="DITA.xsl"?>
<!DOCTYPE topic
  PUBLIC "urn:pubid:com.doctypes.doctypes:doctypes:dita:topic" "topic.dtd">
<topic id="topic_1">
<title>Essay on Education</title>
<topic id="topic_2">
<title>Importance of Education Essay</title>
<p>Following are different types of essay topics</p>
</topic>
<topic id="topic_3">
<title>Essay on Music</title>
<p>Education is the systematic process of improving learning</p>
<ul>
<li><p><b>Find understandable essay.</b> Education essay is the most important</p></li>
<li><p><b>Education is the act.</b> It helps us to easily understand and deal with any problem.</p></li>
</ul>
<p>It improves our knowledge, skill, confidence level and personality.</p>
</topic>
</topic>

Please give me suggestion on this and thanks in advance


Solution

  • If you use XSLT 2.0 as indicated you can use for-each-group starting-with="h1":

    <xsl:output
        method="xml"
        indent="yes"
        omit-xml-declaration="no"
        doctype-public="urn:pubid:com.doctype.doctypes:doctypes:dita:topic"
        doctype-system="topic.dtd"/>
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="/">
            <xsl:processing-instruction name="xml-stylesheet">type="text/xsl" href="dita.xsl"</xsl:processing-instruction>
            <xsl:apply-templates select="//Body"/>
        </xsl:template>
    
        <xsl:template match="Body">        
                <xsl:for-each-group select="*" group-starting-with="h1">
                    <topic>
                        <xsl:attribute name="id">topic_<xsl:number count="h1 | h2"/></xsl:attribute>
                        <title>
                            <xsl:apply-templates select="node()"/>
                        </title>
                        <xsl:for-each-group select="current-group() except ." group-starting-with="h2">
                            <topic>
                                <xsl:attribute name="id">topic_<xsl:number count="h1 | h2"/></xsl:attribute>
                                <title>
                                    <xsl:apply-templates select="node()"/>
                                </title>
                                <xsl:apply-templates select="current-group() except ."
    />                        </topic>
                        </xsl:for-each-group>
                    </topic>
                </xsl:for-each-group>
        </xsl:template>
    </xsl:transform>
    

    See http://xsltransform.net/ncntCSQ/2.