I want to remove the two paragraphs by using that attribute value, I tried the below things, but it's occurring in output,
My input XML is:
<chapter outputclass="chapter-Body">
<body class="- chapter/body ">
<p class="- chapter/p ">why now?</p>
<p class="- chapter/p " outputclass="Image_Size">Banner</p>
<fig>
<image href="3.jpg" outputclass="Fig-Image_Ref"/>
</fig>
<p class="- chapter/p ">But for others, it may not be.</p>
<image ref="4.png" outputclass="Image_Ref"/>
<p class="- chapter/p " outputclass="Image_Size">Small</p>
<p class="- chapter/p ">As result</p>
</body>
</chapter>
XSL I used:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="chapter[@outputclass='chapter-Body']">
<body>
<text>
<text_top><p><xsl:value-of select="body/fig/preceding-sibling::p[1]"/></p>
</text_top>
<text_bottom><p><xsl:value-of select="body/fig/following-sibling::p[1]"/></p>
<p><xsl:value-of select="body/fig/following-sibling::p[2]"/></p>
</text_bottom>
</text>
<xsl:apply-templates/>
</body>
</xsl:template>
<xsl:template match="p[@outputclass='Image_Size']"/>
</xsl:stylesheet>
XML output I got as:
<body>
<text>
<text_top>
<p>Banner</p>
</text_top>
<text_bottom>
<p>But for others, it may not be.</p>
<p>Small</p>
</text_bottom>
</text>
</body>
But I'm expecting to be like:
<body>
<text>
<text_top>
<p>why now?</p>
</text_top>
<text_bottom>
<p>But for others, it may not be.</p>
<p>As result</p>
</text_bottom>
</text>
</body>
I used apply templates of that particular two paras but it's coming in output. How can I fix this using the same XSLT?
The order of the preceding-sibling axis is the reverse document order, so when you do body/fig/preceding-sibling::p[1]
, this gets the p
that immediately precedes the fig
element. You need the one before, so you should be doing body/fig/preceding-sibling::p[2]
.
Similarly, you want the 1st and 3rd p
elements following fig
so you should adjust the indexes accordingly for that too. Note that your current template that matches p[@outputclass='Image_Size']
does not get used at all, because there is nothing in the XSLT that does an xsl:apply-templates
to select them.
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="chapter[@outputclass='chapter-Body']">
<body>
<text>
<text_top>
<p><xsl:value-of select="body/fig/preceding-sibling::p[2]"/></p>
</text_top>
<text_bottom>
<p><xsl:value-of select="body/fig/following-sibling::p[1]"/></p>
<p><xsl:value-of select="body/fig/following-sibling::p[3]"/></p>
</text_bottom>
</text>
</body>
</xsl:template>
</xsl:stylesheet>
Having said that, it looks what you are trying to achieve is to select all p
elements preceding and following the fig
, with the exception of the ones with an outputclass of "Image_Size".
If that is the case, try this more generic XSLT. Note how the template that matches p[@outputclass='Image_Size']
is now used, because of the xsl:apply-templates
in the first template.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="chapter[@outputclass='chapter-Body']">
<body>
<text>
<text_top>
<xsl:apply-templates select="body/fig/preceding-sibling::p" />
</text_top>
<text_bottom>
<xsl:apply-templates select="body/fig/following-sibling::p" />
</text_bottom>
</text>
</body>
</xsl:template>
<xsl:template match="p[@outputclass='Image_Size']"/>
<xsl:template match="p">
<p><xsl:value-of select="." /></p>
</xsl:template>
</xsl:stylesheet>