最初に、関数を定義します。ノードセットをアイテムのリストとして返す必要があります。項目には、要素 (コメントや処理命令も含む)、文字列、およびタプルを含めることができます。
ハードコードされた例は次のようになります。
from lxml import etree
def myFunc(context, parm):
em = etree.Element('em')
em.text = 'text'
return ['some sample ', em]
この場合、 parmパラメーターは必要ないことに注意してください。ただし、 myns:my-funcへの呼び出しでパラメーターを渡すコード例と一致させるために、ここに含めました。
また、 fragments_fromstringを使用してノード セットを作成する場合は、手動で作成するのではなく、関数の定義がさらに簡単になります。
def myFunc(context, parm):
import lxml.html
return lxml.html.fragments_fromstring('some sample <em>text</em>')
次に、名前空間を設定して関数名を登録する必要があります。
myns = etree.FunctionNamespace('http://example.org/myNamespace')
myns['my-func'] = myFunc
最後に、次のように XSLT スタイルシート内から使用できます。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myns="http://example.org/myNamespace">
<xsl:template match="/">
<xsl:variable name="result" select="myns:my-func(./*)" />
<xsl:for-each select="$result">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
スタイルシートで使用される名前空間 URL は、 FunctionNamespaceに登録されているものと一致する必要があることに注意してください。
このスタイルシートをxsltという文字列にロードしたと仮定すると、変換の例は次のようになります。
root = etree.XML('<root></root>')
doc = etree.ElementTree(root)
transform = etree.XSLT(etree.XML(xslt))
res = transform(doc)
完全な動作例については、このペーストビン リンクを参照してください。