2013-07-11 11 views
5

zakładając Mam funkcja XPath Dzwonię z XSL przekształcać za pomocą lxml (z libxml i libxslt), np:Jak mogę zwrócić fragment tekstu z funkcji XPath?

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

Od tej funkcji, chciałbym wrócić fragment XML, który składa następujący:

some sample <em>text</em> 

pyton funkcja my_func jest utworzenie poprawnego użycia lxml być dostępna za pośrednictwem arkusza XSL lxml.html.fragments_fromstring i stosowane w celu uzyskania wyników, które są w następującym formacie:

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

Jak mogę powrócić do tej listy, więc może być używany później w XSL przekształcać ze zmiennej jakby to były zbierane od wyrażenia XPath bezpośrednio w kontekście XSL? Wydaje się, że za każdym razem, gdy przekazuję listę łańcuchów z powrotem do procesora XSL, lxml zgłasza wyjątek.

+1

Jakie jest twoje pytanie? Czy chcesz wiedzieć, w jaki sposób można uzyskać dostęp do funkcji Python z XML? Czy masz już Python połączony z procesorem XSLT i zapewnia on różne wyniki od tego, czego potrzebujesz? Jakie są te wyniki i jak można się spodziewać tehm? Z jakiego procesora XSLT korzystasz? – FrankPl

+0

@unpluggd Jaka część mojej odpowiedzi nie działała dla ciebie?Czy pomogłoby, gdybym dostarczył coś w rodzaju powiązania pastebin z pełnym przykładem roboczym? –

+0

@JamesHolderness Jeśli mógłbyś podać przykład pracy, który byłby wspaniały! Osobiście wypróbowałem twoje podejście i nie zadziałało to dla mnie, co skłoniło mnie do spróbowania tworzenia "inteligentnych ciągów" obiektów i innych rozwiązań, które nie działały. W każdym razie przyznaję ci nagrodę i przyjmuję twoją odpowiedź z dobrym przykładem. Dzięki! –

Odpowiedz

3

Pierwszą rzeczą jest zdefiniowanie swojej funkcji. Musi zwrócić zestaw węzłów jako listę elementów. Elementy mogą zawierać elementy (również komentarze i instrukcje przetwarzania), łańcuchy i krotki.

ustalony Przykładem może wyglądać następująco:

from lxml import etree 

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

Należy pamiętać, że parmezanem parametr nie jest konieczne w tym przypadku, ale podaję go tutaj, aby dopasować swój przykładowy kod, który wyprzedza parametr w wywołaniu myns: my-func.

A jeśli chcesz użyć fragments_fromstring do skonstruowania zestawu węzłów, zamiast budowania go ręcznie, definicja funkcji staje się jeszcze prostsza.

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

Następnie należy ustawić przestrzeń nazw i zarejestrować nazwę funkcji.

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

I wreszcie można go używać z poziomu arkusza stylów XSLT tak:

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

Uwaga URL nazw używane w arkuszu stylów musi być zgodny z jedną zarejestrowaną w FunctionNamespace.

Teraz zakładając już załadowany arkusz stylów na ciąg znaków o nazwie XSLT, przykład przekształcić może wyglądać następująco:

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

Pełny przykład roboczych, zobacz ten pastebin link.

+0

Używam Pythona 2.7.3 i lxml 3.2.1, uruchomiłem kod pastebin i otrzymałem komunikat o błędzie: 'XSLTApplyError: Nie udało się przetestować wyrażenia zmiennej 'result''. –

+0

@unpluggd Właśnie zrobiłem czyste zainstalować python 2.7.3 z [here] (http://www.python.org/download/releases/2.7.3/) (Windows x86 MSI Installer) i lxml 3.2.1 z [here] (https://pypi.python.org/pypi/lxml/3.2.1) (instalator Windows 32bit - lxml-3.2.1.win32-py2.7.exe), a mój przykład nadal działa dobrze dla mnie. Czy to może być problem z systemem operacyjnym? Jesteś na Linuksie? Tak czy inaczej, warto spróbować ponownie zainstalować pythona i lxml. –

+0

@unpluggd Przyszło mi do głowy, że może to być również problem z wersją libxml lub libxslt, której używasz, jeśli zainstalowałeś je osobno. –

Powiązane problemy