2011-01-13 4 views
5

Sto usando lxml 2.2.8 e sto provando a trasformare alcuni file html esistenti in modelli django. l'unico problema che sto avendo è che lxml urlencode il nome dell'ancora e gli attributi href. per esempio:C'è un modo per disabilitare l'urlencoding degli attributi di ancoraggio in lxml

<xsl:template match="a"> 
<!-- anchor attribute href is urlencoded but the title is escaped --> 
<a href="{{{{item.get_absolute_url}}}}" title="{{{{item.title}}}}"> 
    <!-- name tag is urlencoded --> 
    <xsl:attribute name="name">{{item.name}}</xsl:attribute> 
    <!-- but other attributes are not --> 
    <xsl:attribute name="nid">{{item.nid}}</xsl:attribute> 
    <xsl:attribute name="class">{{item.class_one}}</xsl:attribute> 
    <xsl:apply-templates/> 
</a> 

produce html come questo:

<a href="%7B%7Bitem.get_absolute_url%7D%7D" 
    title="{{item.title}}" name="%7B%7Bitem.name%7D%7D" 
    nid="{{item.nid}}" class="{{item.class_one}}">more info</a> 

quello che sto cercando per è questo:

<a href="{{item.get_absolute_url}}">more info</a> 

c'è un modo per disattivare il (automatico) urlencoding che lxml sta facendo?

qui è (praticamente) il codice che sto usando per generare e analizzare il file:

from lxml import etree, html 
from StringIO import StringIO 

doc = StringIO(
'''<html> 
<head> 
    <title>An experiment</title> 
</head> 
<body> 
<p class="one">This is an interesting paragraph detailing the inner workings of something</p> 
<p class="two">paragraph with <a href="/link/to/more">more info</a></p> 
<p>posted by: me</p> 
</body> 
</html>''') 

stylesheet = StringIO(
'''<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xhtml="http://www.w3.org/1999/xhtml" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
exclude-result-prefixes="xhtml xsl"> 
<xsl:template match="p[@class='one']"> 
    <xsl:copy> 
     <!-- when adding an attribute with the xsl:attribute tag --> 
     <!-- the curly braces are not escaped, ie you dont have --> 
     <!-- to double them up --> 
     <xsl:attribute name="class">{{item.class_one}}</xsl:attribute> 
     <xsl:attribute name="nid">{{item.nid}}</xsl:attribute> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="p[@class='two']"> 
    <!-- but double 'em up in this instance --> 
    <p class="{{{{item.class_two}}}}"> 
     <xsl:apply-templates/> 
    </p> 
</xsl:template> 

<xsl:template match="a"> 
    <!-- anchor attribute href is urlencoded but the title is escaped --> 
    <a href="{{{{item.get_absolute_url}}}}" title="{{{{item.title}}}}"> 
     <!-- name tag is urlencoded --> 
     <xsl:attribute name="name">{{item.name}}</xsl:attribute> 
     <!-- but oher attributes are not --> 
     <xsl:attribute name="nid">{{item.nid}}</xsl:attribute> 
     <xsl:attribute name="class">{{item.class_one}}</xsl:attribute> 
     <xsl:apply-templates/> 
    </a> 
</xsl:template> 

<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates /> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 
''') 
def parse_doc(): 
    xsl = etree.parse(stylesheet) 
    trans = etree.XSLT(xsl) 
    root = html.parse(doc, etree.HTMLParser(encoding="windows-1252")) 
    transformed = trans(root) 
    print html.tostring(transformed) 

if __name__ == '__main__': 
    parse_doc() 

con l'eccezione che questi file sono tutti HTML malformato :)

+0

Questo succede ancora se dichiari '' nel tuo programma XSLT? – Tomalak

+0

Solo Altova può riprodurre questo con la serializzazione del metodo 'html'. MSXSL 3/4 e Saxon no. –

+0

@Tomalak Ho provato a cambiare il metodo di output in xml e non ha alcun effetto – AnvilRockRoad

risposta

4

forse è possibile utilizzare il codice XML invece del serializzatore HTML.

>>> from lxml import etree, html 
>>> 
>>> t = etree.XML('<a href="{{x}}" />') 
>>> 
>>> etree.tostring(t) 
'<a href="{{x}}"/>' 
>>> html.tostring(t) 
'<a href="%7B%7Bx%7D%7D"></a>' 
+0

cambiando da html a etree funziona con il mio codice di esempio, vedrò se riesco a farlo funzionare sulle cose reali – AnvilRockRoad

+0

come Alejandro ha sottolineato che lxml sta solo facendo quello che dovrebbe . C'è voluto del lavoro perché l'html è veramente, veramente, malformato, ma quello che ho finito è stato usare etree.html per analizzare il file iniziale e averlo eseguito attraverso la trasformazione xslt.Quindi ho appena estratto gli elementi che volevo e ho usato etree.tostring per sputare il mio markup. – AnvilRockRoad

+0

@AnvilRockRoad: In XSLT 1.0 è anche possibile utilizzare il metodo di serializzazione 'xml' e seguire le linee guida XHTML-serve-come-HTML. In XSLT 2.0 hai il controllo per consentire questo comportamento o meno. –

3

Sembra che dovrebbe essere l'uscita corretta per html metodo di serializzazione.

Da http://www.w3.org/TR/xslt#section-HTML-Output-Method

Il metodo html uscita dovrebbe sfuggire caratteri non ASCII in notazione URI attributo valori utilizzando il metodo consigliato in Section B.2.1 del HTML 4.0 raccomandazione.

per XSLT 2.0 da http://www.w3.org/TR/xslt-xquery-serialization/#HTML_ESCAPE-URI-ATTRIBUTES

Se il parametro escape-uri-attributes ha il valore yes, il metodo di uscita HTML applicare MUSTURI escaping-URI attribute values, ad eccezione di quello relativo URI NON DEVE essere assolutizzato.