在ElementTree文本中插入标签
我正在使用PythonElementTree模块来操作HTML。 我想强调某些词,我目前的解决方案是:
for e in tree.getiterator():
for attr in 'text', 'tail':
words = (getattr(e, attr) or '').split()
change = False
for i, word in enumerate(words):
word = clean_word.sub('', word)
if word.lower() in glossary:
change = True
words[i] = word.replace(word, '<b>' + word + '</b>')
if change:
setattr(e, attr, ' '.join(words))
上面检查了每个元素的文本,并强调了它找到的重要单词。 然而,它是通过在文本属性中嵌入HTML标记来实现这一点的,在呈现时会对其进行转义,因此我需要使用:
html = etree.tostring(tree).replace('>', '>').replace('<', '<')
这让我不舒服,所以我想正确地做它。 然而,要嵌入一个新元素,我需要在"Text"和"Tail"属性之间切换,以便强调的文本出现在相同的位置。当像上面那样迭代时,这将是非常棘手的。
任何如何正确完成此操作的建议都将不胜感激。我肯定我在API中遗漏了一些东西!
xslt
您还可以使用推荐答案和一个定制的xPath函数来完成此操作。
下面显示的是一个示例。它仍然需要做一些工作,例如清理元素末尾的多余空格和处理混合文本,但这是另一种想法。给定此输入:
<html>
<head>
</head>
<body>
<p>here is some text to bold</p>
<p>and some more</p>
</body>
</html>
和词汇表包含两个词:一些,粗体
则示例输出为:
<?xml version="1.0"?>
<html>
<head/>
<body>
<p>here is <b>some</b> text to <b>bold</b> </p>
<p>and <b>some</b> more </p>
</body>
</html>
这是代码,我也发布在http://bkc.pastebin.com/f545a8e1d
from lxml import etree
stylesheet = etree.XML("""
<xsl:stylesheet version="1.0"
xmlns:btest="uri:bolder"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*">
<xsl:copy />
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name(.)}">
<xsl:copy-of select="@*" />
<xsl:apply-templates select="text()" />
<xsl:apply-templates select="./*" />
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:copy-of select="btest:bolder(.)/node()" />
</xsl:template>
</xsl:stylesheet>
""")
glossary = ['some', 'bold']
def bolder(context, s):
results = []
r = None
for word in s[0].split():
if word in glossary:
if r is not None:
results.append(r)
r = etree.Element('r')
b = etree.SubElement(r, 'b')
b.text = word
b.tail = ' '
results.append(r)
r = None
else:
if r is None:
r = etree.Element('r')
r.text = '%s%s ' % (r.text or '', word)
if r is not None:
results.append(r)
return results
def test():
ns = etree.FunctionNamespace('uri:bolder') # register global namespace
ns['bolder'] = bolder # define function in new global namespace
transform = etree.XSLT(stylesheet)
print str(transform(etree.XML("""<html><head></head><body><p>here is some text to bold</p><p>and some more</p></body></html>""")))
if __name__ == "__main__":
test()
相关文章