2013-07-11 10 views
5

se io hanno una funzione XPath Chiamo da una trasformazione XSL utilizzando lxml (con libxml e libxslt), ad esempio:Come posso restituire un frammento di testo da una funzione XPath?

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

Da questa funzione, vorrei restituire un frammento XML che consiste il seguente:

some sample <em>text</em> 

il pitone funzione my_func viene impostata ad un corretto utilizzando lxml a essere disponibili tramite il foglio di stile XSL, e utilizzato lxml.html.fragments_fromstring per ottenere i risultati che sono nel formato:

012.

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

Come posso restituire questa lista in modo che possa essere utilizzato in seguito nella trasformazione XSL dalla variabile come se fosse raccolto da un'espressione XPath direttamente nel contesto XSL? Sembra che ogni volta che passo un elenco di stringhe al processore XSL, lxml genera un'eccezione.

+1

Qual è la tua domanda? Vuoi sapere come puoi accedere a una funzione Python da XML? O hai già il Python collegato al tuo processore XSLT e fornisce risultati diversi da quello che ti serve? Quali risultati sono questi e come ti aspetti tehm? Quale processore XSLT stai usando? – FrankPl

+0

@unpluggd Quale parte della mia risposta non ha funzionato per te?Sarebbe d'aiuto se fornissi qualcosa come un collegamento pastebin con un esempio operativo completo? –

+0

@JamesHolderness Se potessi fornire un esempio funzionante sarebbe meraviglioso! Ho provato personalmente il tuo approccio e non ha funzionato per me, il che mi ha portato a provare a creare oggetti "smart string" e altre soluzioni che non hanno funzionato. Ti ho comunque assegnato la taglia e accetterò la tua risposta con un esempio funzionante. Grazie! –

risposta

3

La prima cosa è definire la tua funzione. È necessario restituire il set di nodi come un elenco di elementi. Gli elementi possono includere elementi (anche commenti e istruzioni di elaborazione), archi e tuple.

Un esempio hardcoded potrebbe assomigliare a questo:

from lxml import etree 

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

Nota che il parametro parm non è necessario in questo caso, ma ho incluso qui per abbinare il vostro codice di esempio che sta passando un parametro nella chiamata a myns: my-func.

E se si desidera utilizzare fragments_fromstring per creare il proprio set di nodi, anziché crearlo manualmente, la definizione della funzione diventa ancora più semplice.

def myFunc(context, parm):   
    import lxml.html 
    return lxml.html.fragments_fromstring('some sample <em>text</em>') 

Successivamente è necessario impostare lo spazio dei nomi e registrare il nome della funzione.

myns = etree.FunctionNamespace('http://example.org/myNamespace') 
myns['my-func'] = myFunc 

E, infine è possibile utilizzarlo all'interno di un foglio di stile XSLT come questo:

<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> 

Nota l'URL dominio utilizzato nel foglio di stile deve corrispondere a quello registrato nella FunctionNamespace.

Ora supponendo che hai caricato questo foglio di stile in una stringa chiamata XSLT, un esempio trasformare potrebbe essere simile a questo:

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

Per un esempio di lavoro completo, vedere questo pastebin link.

+0

Sto usando Python 2.7.3 e lxml 3.2.1, ho eseguito il codice pastebin e ho ricevuto un errore: 'XSLTApplyError: Impossibile valutare l'espressione della variabile 'result''. –

+0

@unpluggd Ho appena fatto una pulizia installazione di python 2.7.3 da [here] (http://www.python.org/download/releases/2.7.3/) (il programma di installazione MSI per Windows x86) e lxml 3.2.1 da [qui] (https://pypi.python.org/pypi/lxml/3.2.1) (l'installer di Windows 32 bit - lxml-3.2.1.win32-py2.7.exe), e il mio esempio funziona ancora bene per me. Potrebbe essere un problema del sistema operativo? Sei su Linux? Ad ogni modo, potrebbe valere la pena provare a reinstallare python e lxml. –

+0

@unpluggd Mi è appena venuto in mente che potrebbe anche essere un problema con la versione di libxml o libxslt che stai usando se li hai installati separatamente. –

Problemi correlati