Python:从XML文件中提取HTML

0 投票
4 回答
1400 浏览
提问于 2025-04-15 16:29

我的XML文件长这样:

 <strings>
      <string>Bla <b>One &amp; Two</b> Foo</string>
 </strings>

我想提取每个<string>里的内容,同时保留里面的标签。也就是说,我希望能得到这样的Python字符串:u"Bla <b>One & Two</b> Foo"。或者,我也可以接受u"Bla <b>One & Two</b> Foo",然后自己去替换那些特殊字符。

我现在用的是lxml这个库,它让我可以遍历嵌套的标签,但这样就会漏掉那些不在标签里的文本。或者我也可以遍历所有的文本内容(itertext),但这样又会丢失标签的信息。我可能遗漏了什么。

如果可以的话,我更希望继续使用lxml,不过如果有必要的话,我也可以换成其他库。

4 个回答

0

不管用什么编程语言,比较简单的XSLT模板就能解决这个问题。

你可以定义一些规则,告诉程序哪些标签要保留,哪些标签要转换成文本。

当然,你也可以使用递归函数,配合一个合适的DOM实现(比如minidom),手动处理这些标签。

(伪代码)

def Function(tag):
   if tag.NodeType = "#text": return tag.innerText
   text=""
   if tag.ElementName in allowedTags:
       text="<%s>"%tag.ElementName
   text += [Function(subtag) for subtag in tag.childs]
   if tag.ElementName in allowedTags:
       text+="</%s>"%tag.ElementName
   return text
2

试试使用 etree.tostring 这个方法。

outer = etree.tostring(string_elem, method='html')
inner = re.match("^[^>]+>(.*)<[^<]+$", outer).groups(1)[0]
3

可能有更好的方法来处理由 xpath() 函数返回的对象,但我对 lxml 还不够熟悉,所以我写了一个函数来返回节点的文本值。不过,下面的内容展示了一种解决这个问题的通用方法:

>>> from lxml import etree
>>> from StringIO import StringIO
>>> def node_text(n):
        try:
            return etree.tostring(n, method='html', with_tail=False)
        except TypeError:
            return str(n)

>>> f = StringIO('<strings><string>This is <b>not</b> how I plan to escape.</string></strings>')
>>> x = etree.parse(f)
>>> ''.join(node_text(n) for n in x.xpath('/strings/string/node()'))
'This is <b>not</b> how I plan to escape.'

撰写回答