Say I have an HTML file like this:
<ol>
<li>item 1</li>
<li>item 2</li>
</ol>
<ul>
<li>item 3</li>
<li>item 4</li>
<li> </li>
</ul>
For those list items, whether it being in an ordered or unordered list, I want to wrap the text of that <li> element in a <p> tag. So that the processed HTML file would look like this:
<ol>
<li><p>item 1</p></li>
<li><p>item 2</p></li>
</ol>
<ul>
<li><p>item 3</p></li>
<li><p>item 4</p></li>
<li> </li>
</ul>
Here is the .xsl file I have written:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match='/'>
<xsl:apply-templates select='*' />
</xsl:template>
<xsl:template match='*'>
<xsl:copy-of select='.' />
</xsl:template>
<xsl:template match='li'>
<xsl:if test='normalize-space(.)'>
<xsl:element name='p'>
<xsl:value-of select='.' />
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
However, this does not work. Can anyone tell me where I did wrong? Thanks.
CodePudding user response:
You have a template matching li
, but it is never applied because the template processing its parent element copies all its content as is. Also, your 1st template is redundant; the built-in template rules will do that for you.
Try:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match='*'>
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match='li[normalize-space()]'>
<xsl:copy>
<p>
<xsl:value-of select='.' />
</p>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
CodePudding user response:
Thanks to @michael.hor257k. I have solved this problem. The code that works is as follows:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match='*'>
<xsl:copy select='.'>
<xsl:apply-templates select='*'/>
</xsl:copy>
</xsl:template>
<xsl:template match='li[normalize-space()]'>
<xsl:copy>
<p>
<xsl:value-of select='.' />
</p>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>