如何在XML中输出非转义元素标签?
How Can I Output Non-Escaped Element Tag In XML?
我有一个继承的 Python 脚本,我的问题是现在 paragraph
变量中有一段文本包含锚标记。例如:
This is text with a <a href="http://somewebsite.com">Link</a> in it.
然而,我需要做的是将锚标记转换为 apxh
名称 space,因此上面的行应该如下所示:
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>
不要将您的内容作为文字文本注入——将其渲染到 DOM 内容中,使用隐式使默认命名空间与映射到 aphx
:[=22 的命名空间映射相同的命名空间映射=]
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
保留在默认名称空间中的内容(我们使用xmlns=
里面的人工根)。
在评论区的讨论中,发现你们的一些生产数据是这样的:
u'John Doe: 360-555-4546; <a href=\"mailto:john.doe@website.com;\">John.mailto:john.doe@website.com</a> twitter.com/JohnDoe'
etree.fromstring()
将在给定此输入时抛出异常,因为它因反斜杠而无效 XML(或有效的 XHTML)。
如果您非常确定 \"
永远不会出现在有效输入中,您可以考虑:
text_el = etree.fromstring(
'<root xmlns="http://www.w3.org/1999/xhtml">' +
text.replace('\"', '"') +
'</root>')
我有一个继承的 Python 脚本,我的问题是现在 paragraph
变量中有一段文本包含锚标记。例如:
This is text with a <a href="http://somewebsite.com">Link</a> in it.
然而,我需要做的是将锚标记转换为 apxh
名称 space,因此上面的行应该如下所示:
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>
不要将您的内容作为文字文本注入——将其渲染到 DOM 内容中,使用隐式使默认命名空间与映射到 aphx
:[=22 的命名空间映射相同的命名空间映射=]
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
保留在默认名称空间中的内容(我们使用xmlns=
里面的人工根)。
在评论区的讨论中,发现你们的一些生产数据是这样的:
u'John Doe: 360-555-4546; <a href=\"mailto:john.doe@website.com;\">John.mailto:john.doe@website.com</a> twitter.com/JohnDoe'
etree.fromstring()
将在给定此输入时抛出异常,因为它因反斜杠而无效 XML(或有效的 XHTML)。
如果您非常确定 \"
永远不会出现在有效输入中,您可以考虑:
text_el = etree.fromstring(
'<root xmlns="http://www.w3.org/1999/xhtml">' +
text.replace('\"', '"') +
'</root>')