Home > Blockchain >  How to create a new node under the current node that wraps the current node's text?
How to create a new node under the current node that wraps the current node's text?

Time:10-29

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>
  • Related