how to use a variable as a value in xslapply-templates?

Your attempt:

<xsl:template match="/products">
    <xsl:apply-templates select="product[id=$item_num]" />
</xsl:template>

<xsl:template match="id" >
    <p><xsl:value-of select="."/></p>
    <xsl:value-of select="following-sibling::feature" disable-output-escaping="yes"/>
</xsl:template>

applies templates to <product> nodes, but has a template for <id> nodes.

Make a template for <product> nodes.

<xsl:template match="product">
    <p><xsl:value-of select="id"/></p>
    <xsl:value-of select="feature" disable-output-escaping="yes" />
</xsl:template>

Whenever XSLT cannot find a template for a specific node, it falls back to default behavior. Default behavior is “copy child text nodes to output, and apply templates to child elements”. This explains why you see what you see with your code.


Regarding your other issue: .find('...') returns XML nodes, not string values, i.e. .find('id') finds an <id> element. You wanted to pass the .text of the found node as the XSLT parameter, not the node itself:

import lxml.etree as ET

doc = ET.parse('source.xml')
xslt = ET.parse('modify.xsl')
transform = ET.XSLT(xslt)

products = doc.findall('product')

for product in products:
    i = product.find('id').text
    describ = transform(doc, item_num=i)
    with open(f'file_nr_{i}.html', 'wb') as f:
        f.write(describ)

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top