2011-01-13 3 views
5

estoy usando lxml 2.2.8 y tratando de transformar algunos archivos HTML existentes en las plantillas de Django. el único problema que estoy teniendo es que lxml urlencodes el nombre de anclaje y atributos href. por ejemplo:¿Hay una manera de desactivar URLEncoding de atributos de anclaje en 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 así:

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

lo que estoy tratando de decir esto:

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

hay una manera de desactivar el (automático) urlencoding que lxml está haciendo?

aquí es (básicamente) el código que estoy utilizando para generar y analizar el archivo:

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 la excepción de que estos archivos son todos HTML incorrecto :)

+0

¿Esto todavía sucede si declara '' en su programa XSLT? Sólo – Tomalak

+0

Altova puede reproducir este método de serialización con 'html'. MSXSL 3/4 y Saxon no. –

+0

@Tomalak Yo trate de cambiar el método de salida de XML y se dio tienen ningún efecto – AnvilRockRoad

Respuesta

4

Tal vez usted puede utilizar el código XML en lugar del serializador de 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

cambiar de html en etree no trabajar con mi código de ejemplo, voy a ver si puedo conseguir que funcione en la materia verdadera – AnvilRockRoad

+0

como Alejandro señaló lxml sólo está haciendo lo que se supone que . Tomó un poco de trabajo, ya que el HTML es muy, muy, mal formado, pero lo que terminó haciendo era utilizar etree.html para analizar el archivo inicial y corrió que a través de la transformación XSLT.Luego extraje los elementos que quería y utilizo etree.tostring para escupir mi marcado. – AnvilRockRoad

+0

@AnvilRockRoad: en XSLT 1.0 también puede usar el método de serialización 'xml' y seguir las pautas de XHTML-serve-as-HTML. En XSLT 2.0 tiene el control para permitir este comportamiento o no. –

3

Parece que debe ser la salida adecuada para html método de serialización.

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

html El método de salida debe escapar caracteres no ASCII en URI atributo valores utilizando el método recomendado en Section B.2.1 del HTML 4.0 Recomendación.

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

Si el parámetro escape-uri-attributes tiene el valor yes, el método de salida HTML MUST aplicar URI escaping-URI attribute values, excepto que los URIs relativos NO DEBE ser absolutizado

Cuestiones relacionadas