【问题标题】:Is there a way to disable urlencoding of anchor attributes in lxml有没有办法在 lxml 中禁用锚属性的 urlencoding
【发布时间】:2011-01-13 19:57:38
【问题描述】:

我正在使用 lxml 2.2.8 并尝试将一些现有的 html 文件转换为 django 模板。 我遇到的唯一问题是 lxml urlencodes 锚名称和 href 属性。 例如:

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

生成这样的html:

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

我想要的是:

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

有没有办法禁用 lxml 正在执行的(自动)urlencoding?

这里(基本上)是我用来生成和解析文件的代码:

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

除了这些文件都是格式错误的 html :)

【问题讨论】:

  • 如果您在 XSLT 程序中声明 &lt;xsl:output method="xml" /&gt;,还会发生这种情况吗?
  • 只有 Altova 可以通过html 方法序列化来重现这一点。 MSXSL 3/4 和撒克逊人没有。
  • @Tomalak 我确实尝试将输出方法更改为 xml,但没有任何影响
  • xml 序列化方法的这种行为是一个错误
  • 所以 lxml 不应该将花括号转换为“%7B”?是的,我有点密集:)

标签: python xslt urlencode lxml


【解决方案1】:

也许您可以使用 XML 代替 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>'

【讨论】:

  • 从 html 更改为 etree 确实适用于我的示例代码,我会看看是否可以让它在真实的东西上工作
  • 正如 Alejandro 指出的那样,lxml 只是在做它应该做的事情。这需要一些工作,因为 html 真的,真的,格式错误,但我最终做的是使用 etree.html 来解析初始文件并通过 xslt 转换运行它。然后我只提取了我想要的元素并使用 etree.tostring 吐出我的标记。
  • @AnvilRockRoad:在 XSLT 1.0 中,您还可以使用xml 序列化方法并遵循 XHTML-serve-as-HTML 指南。在 XSLT 2.0 中,您可以控制是否允许这种行为。
【解决方案2】:

看起来应该html序列化方法的正确输出。

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

html 输出方法应该转义 URI 属性中的非 ASCII 字符 使用推荐的方法的值 HTML 4.0 的Section B.2.1 推荐。

对于来自 http://www.w3.org/TR/xslt-xquery-serialization/#HTML_ESCAPE-URI-ATTRIBUTES 的 XSLT 2.0

如果escape-uri-attributes 参数的值为yes,则 HTML 输出方法必须URI escaping 应用于URI attribute values,除了相对URI 不得绝对化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    相关资源
    最近更新 更多