2013-07-11 14 views
5

私は例えば、私は(libxmllibxsltで)lxmlを使用して変換XSLから呼んでいるXPath関数を持っていると仮定すると:XPath関数からテキストフラグメントを返すにはどうすればよいですか?

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

この機能から、私は構成されてXMLフラグメントを返したいのですが次

some sample <em>text</em> 

機能my_funcが正しくフォーマットされている結果を得るためにセットアップXSLスタイルシートを介して利用できるようにlxmlを使用し、そしてlxml.html.fragments_fromstring使用されるのpython:

それはXSLに後で使用することができますので、私はこのリストを返すことができますどのように

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

それはXSLコンテキストで直接XPath式から収集したかのように変数から変換?私は文字列のリストをXSLプロセッサに戻すたびに例外をスローします。lxml

+1

ご質問はありますか? XMLからPython関数にアクセスする方法を知りたいですか?あるいは、すでにPythonをXSLTプロセッサにリンクしていて、必要なものとは異なる結果が得られますか?どの結果がありますか、どのように期待していますか?どのXSLTプロセッサを使用していますか? – FrankPl

+0

@unpluggd私の答えのどの部分がうまくいかなかったのですか?ペーストビンリンクのようなものを完全な実例で提供すれば、それは役に立ちますか? –

+0

@JamesHoldernessすばらしい作業例を提供できる場合は!私は個人的にあなたのアプローチを試してみましたが、それは私のためには機能しませんでした。これは、 "スマートな文字列"のオブジェクトと、うまくいかなかった他のソリューションを作成しようとしました。とにかく私はあなたに賞金を授与し、実際の例であなたの答えを受け入れます。ありがとう! –

答えて

3

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

ハードコードされた例は次のようになります。PARMパラメータは、この場合には必要ありませんが、私は通過しているあなたの例のコードを一致させるためにそれをここに含まれたこと

from lxml import etree 

def myFunc(context, parm): 
    em = etree.Element('em') 
    em.text = 'text' 
    return ['some sample ', em] 

注意パラメータを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に登録したものと一致しなければなりません。

root = etree.XML('<root></root>') 
doc = etree.ElementTree(root) 
transform = etree.XSLT(etree.XML(xslt)) 
res = transform(doc) 

完全な作業例については、このpastebin linkを参照してください。

は今、このようになります変換たとえば、あなたが XSLTと呼ばれる文字列に、このスタイルシートをロードしたと仮定します。

+0

私はPython 2.7.3とlxml 3.2.1を使用していますが、pastebinコードを実行してエラーが発生しました: 'XSLTApplyError:変数 'result'の式を評価できませんでした。 ' –

+0

@unpluggd [here](http://www.python.org/download/releases/2.7.3/)(Windows x86 MSIインストーラ)からpython 2.7.3をインストールし、lxml 3.2.1を[ここ](https:///pypi.python.org/pypi/lxml/3.2.1)(Windows 32bitインストーラ - lxml-3.2.1.win32-py2.7.exe)、私の例はまだうまく動作します。それはOSの問題かもしれませんか?あなたはLinuxですか?いずれにせよ、pythonとlxmlを再インストールする価値があるかもしれません。 –

+0

@unpluggd別途インストールしたlibxmlまたはlibxsltのバージョンで問題が発生している可能性があります。 –

関連する問題