2013-07-11 39 views
5

假如我有使用lxml我從XSL調用一個XPath函數變換(與libxmllibxslt),例如:如何從XPath函數返回文本片段?

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

從這個功能,我想返回由XML片段以下:

some sample <em>text</em> 

功能my_func被建立正確使用lxml是通過XSL樣式表可用的,並且用於lxml.html.fragments_fromstring以獲得格式中的結果的蟒:

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

我怎樣才能返回此列表中,以便以後可以用在XSL從變量變換,就好像是從XPath表達式直接在XSL環境下收集的?似乎只要我將字符串列表傳回給XSL處理器lxml就會引發異常。

+1

你的問題是什麼?你想知道如何從XML訪問Python函數嗎?或者,您是否已經將Python鏈接到您的XSLT處理器,並且它會提供您所需的不同結果?這些結果是什麼,你如何期待tehm?你在使用哪種XSLT處理器? – FrankPl

+0

@unpluggd我的答案的哪部分不適合你?如果我提供了一個類似於pastebin鏈接的完整示例,它會有幫助嗎? –

+0

@JamesHolderness如果你能提供一個很棒的工作例子!我親自嘗試過你的方法,但它並不適合我,這導致我嘗試創建「智能字符串」對象和其他無法使用的解決方案。無論如何,我已經爲您頒發了獎金,並將通過一個實例來接受您的答案。謝謝! –

回答

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) 

對於一個完整的工作示例,請參閱本pastebin link

+0

我正在使用Python 2.7.3和lxml 3.2.1,運行pastebin代碼,並得到一個錯誤:'XSLTApplyError:無法評估變量結果的表達式。' –

+0

@unpluggd我剛剛做了一個清理從[here](http://www.python.org/download/releases/2.7.3/)(Windows x86 MSI安裝程序)安裝python 2.7.3,從[here](https:/ /pypi.python.org/pypi/lxml/3.2.1)(Windows 32位安裝程序 - lxml-3.2.1.win32-py2.7.exe),我的例子對我來說仍然很好。它可能是一個操作系統問題?你在Linux上嗎?無論哪種方式,它可能是值得嘗試重新安裝python和lxml。 –

+0

@unpluggd對我來說,它可能也是您使用的libxml或libxslt版本的問題,如果您已單獨安裝這些版本的話。 –