我有一个我继承的Python脚本,我的问题是现在我在paragraph
变量中包含一个包含锚标记的文本块。例如:
This is text with a <a href="http://somewebsite.com">Link</a> in it.
我需要做的是将锚标记转换为apxh
名称空间,以便上面的行看起来像这样:
This is text with a <apxh:a href="http://somewebsite.com">Link</apxh:a> in it.
问题在于我上面输出的方式是:
This is text with a <apxh:a href=\"http://somewebsite.com;\">Link Text;</apxh:a> in it.
我的猜测是,当我在paragraph
上运行for循环时,我需要一些如何查找所有锚标签和文本并执行etree.Element("{%s}a" % nm["apxh"], nsmap=nm)
之类的操作,但我不太确定
这是当前的脚本:
def get_news_feed(request):
articles = models.Article.objects.all().filter(distributable = True)
nm = {
None: "http://www.w3.org/2005/Atom",
"ap": "http://ap.org/schemas/03/2005/aptypes",
"apcm": "http://ap.org/schemas/03/2005/apcm",
"apnm": "http://ap.org/schemas/03/2005/apnm",
"apxh": "http://www.w3.org/1999/xhtml",
}
doc = etree.Element("{%s}feed" % nm[None], nsmap=nm)
for article in articles:
entry = etree.Element("{%s}entry" % nm[None], nsmap=nm)
content = etree.Element("{%s}content" % nm[None], nsmap=nm)
content.set("type", "xhtml")
div = etree.Element("{%s}div" % nm["apxh"], nsmap=nm)
for paragraph in article.body.replace("&", "&").split("\n"):
par = etree.Element("{%s}p" % nm["apxh"], nsmap=nm)
par.text = paragraph
par.text = paragraph.replace("<a", "<apxh:a")
par.text = par.text.replace("</a", "</apxh:a")
par.text = cleanup_entities(par.text)
div.append(par)
content.append(div)
entry.append(content)
doc.append(entry)
output = etree.tostring(doc, encoding="UTF-8", xml_declaration=True, pretty_print=True)
return HttpResponse(output, mimetype="application/xhtml+xml")
这是输出的外观:
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns:ap="http://ap.org/schemas/03/2005/aptypes" xmlns:apxh="http://www.w3.org/1999/xhtml" xmlns:apnm="http://ap.org/schemas/03/2005/apnm" xmlns:apcm="http://ap.org/schemas/03/2005/apcm" xmlns="http://www.w3.org/2005/Atom">
<entry>
<content type="xhtml">
<apxh:div>
<apxh:p>This is some text</apxh:p>
<apxh:p>This is text with a <apxh:a href="http://somewebsite.com">Link</apxh:a> in it.</apxh:p>
<apxh:p>Theater</apxh:p>
</apxh:div>
</content>
</entry>
</feed>
这是目前输出的显示方式:
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns:ap="http://ap.org/schemas/03/2005/aptypes" xmlns:apxh="http://www.w3.org/1999/xhtml" xmlns:apnm="http://ap.org/schemas/03/2005/apnm" xmlns:apcm="http://ap.org/schemas/03/2005/apcm" xmlns="http://www.w3.org/2005/Atom">
<entry>
<content type="xhtml">
<apxh:div>
<apxh:p>This is some text</apxh:p>
<apxh:p>This is text with a <apxh:a href=\"http://somewebsite.com;\">Link Text;</apxh:a> in it.</apxh:p>
<apxh:p>Theater</apxh:p>
</apxh:div>
</content>
</entry>
</feed>
答案 0 :(得分:1)
不要将内容作为文字文本注入 - 将其呈现为DOM内容,使用名称空间映射隐式地使默认名称空间与映射到aphx
的名称空间相同:
import lxml.etree as etree
text='This is text with a <a href="http://somewebsite.com">Link</a> in it.'
text_el = etree.fromstring('<root xmlns="http://www.w3.org/1999/xhtml">' + text + '</root>')
...然后将text_el
的内容放入par
。
这样做可能如下所示:
par = etree.Element('{http://www.w3.org/1999/xhtml}div', nsmap=nm)
par.text = text_el.text
for child_el in text_el[:]:
par.append(child_el)
由于上面使用了nsmap nm
,将其转换回字符串将遵循其中包含的名称空间前缀,因此使用apxh
表示默认名称空间中保留的内容(我们使用{{{ 1}}在人工根里面。)
在评论的讨论中,您的一些生产数据看起来像是:
xmlns=
u'John Doe: 360-555-4546; <a href=\\"mailto:john.doe@website.com;\\">John.mailto:john.doe@website.com</a> twitter.com/JohnDoe'
在给出此输入时会抛出异常,因为它是反斜杠的无效XML(或有效的XHTML)。
如果您确定在有效输入中不会出现etree.fromstring()
,您可能会考虑:
\"