5

lxml( with libxmland )を使用して XSL 変換から呼び出す XPath 関数があるとしますlibxslt。たとえば、次のようになります。

<xsl:template match="/">
  <xsl:variable name="result" select="myns:my-func(./*)" />
  ...
</xsl:template>

この関数から、以下で構成される XML フラグメントを返したいと思います。

some sample <em>text</em>

Python 関数は、XSL スタイルシートを介してmy_func使用できるように正しく設定されており、次の形式の結果を取得するために使用されます。lxmllxml.html.fragments_fromstring

['some sample ', <Element em at 0x106c203b0>]

XSL コンテキストで XPath 式から直接収集されたかのように、後で変数から XSL 変換で使用できるように、このリストを返すにはどうすればよいですか? 文字列のリストを XSL プロセッサに渡すたびにlxml、例外がスローされるようです。

4

1 に答える 1

3

最初に、関数を定義します。ノードセットをアイテムのリストとして返す必要があります。項目には、要素 (コメントや処理命令も含む)、文字列、およびタプルを含めることができます。

ハードコードされた例は次のようになります。

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)

完全な動作例については、このペーストビン リンクを参照してください。

于 2013-07-23T16:06:15.023 に答える