问题
I am using lxml 2.2.8 and trying to transform some existing html files into django templates. the only problem that i am having is that lxml urlencodes the anchor name and href attributes. for example:
<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>
produces html like this:
<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>
what I am trying for is this:
<a href="{{item.get_absolute_url}}">more info</a>
is there a way to disable the (automatic) urlencoding that lxml is doing?
here is (basically) the code I am using to generate and parse the 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()
with the exception that these files are all malformed html :)
回答1:
Maybe you can use the XML instead of the HTML serializer.
>>> 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>'
回答2:
It looks like that should be the proper output for html
serialization method.
From http://www.w3.org/TR/xslt#section-HTML-Output-Method
The
html
output method should escape non-ASCII characters in URI attribute values using the method recommended in Section B.2.1 of the HTML 4.0 Recommendation.
For XSLT 2.0 from http://www.w3.org/TR/xslt-xquery-serialization/#HTML_ESCAPE-URI-ATTRIBUTES
If the
escape-uri-attributes
parameter has the valueyes
, the HTML output method MUST apply URI escaping to URI attribute values, except that relative URIs MUST NOT be absolutized.
来源:https://stackoverflow.com/questions/4684614/is-there-a-way-to-disable-urlencoding-of-anchor-attributes-in-lxml