0

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

4 回答 4

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.'
于 2009-11-29T18:28:44.763 回答
2

尝试etree.tostring

outer = etree.tostring(string_elem, method='html')
inner = re.match("^[^>]+>(.*)<[^<]+$", outer).groups(1)[0]
于 2009-11-29T07:42:09.773 回答
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
于 2009-11-29T08:04:38.520 回答
-1

不使用解析器,而只是纯粹的字符串操作

mystring="""
 <strings>
      <string>Bla <b>One &amp; Two</b> Foo</string>
 </strings>
"""
for s in mystring.split("</string>"):
    if "<string>" in s:
        i = s.index("<string>")
        print s[i+len("<string>"):].replace("&amp;","")
于 2009-11-29T08:39:39.667 回答