我有一个像这样的xml文件:
<data>
<entry>
<word>ABC</word> (this)
</entry>
<entry>
<word>ABC</word> [not this]
</entry>
</data>
我想选择其后代包含“(”,并将(。*)移动到<entry>
文本的节点。即:
<data>
<entry>
(this)
<word>ABC</word>
</entry>
<entry>
<word>ABC</word> [not this]
</entry>
</data>
我正在使用lxml。我试过了:
import lxml.etree as ET
data = ET.parse('sample.xml')
for entry in data.iter('entry'):
A = entry.xpath('.//*[text() = ".*(.*?)"]')
但它不起作用。 “(”可以显示为节点的尾部或节点的文本。
答案 0 :(得分:0)
如果(
在尾部并将其移动到父文本..那么..
In [67]: myxml="""<data>
...: <entry>
...: <word>ABC</word> (this)
...: </entry>
...: <entry>
...: <word>ABC</word> [not this]
...: </entry>
...: </data>"""
In [68]: import StringIO, re, lxml.etree as ET
In [69]: f=StringIO.StringIO(myxml)
In [70]: data=ET.parse(f)
In [71]: print ET.tostring(data)
<data>
<entry>
<word>ABC</word> (this)
</entry>
<entry>
<word>ABC</word> [not this]
</entry>
</data>
In [72]: for elem in data.findall("/entry/"):
...: if re.match(".*\(.*\).*",elem.tail):
...: elem.getparent().text=elem.tail
...: elem.tail=None
...:
In [73]: print ET.tostring(data)
<data>
<entry> (this)
<word>ABC</word></entry>
<entry>
<word>ABC</word> [not this]
</entry>
</data>
答案 1 :(得分:0)
这里有一些问题:
首先,您尝试使用xpath进行正则表达式匹配,但是您正在使用=。您的正则表达式也格式不正确。要在xpath中实际进行正则表达式匹配,您需要执行以下操作:
import lxml.etree as ET
data = ET.parse('sample.xml')
regexpNS = "http://exslt.org/regular-expressions"
for entry in data.iter('entry'):
A = entry.xpath('.//*[re:test(text(), ".*\(.*\).*")]',
namespaces={'re':regexpNS})
不幸的是,这实际上对你不起作用,因为你想要尾部的文本,text()
中没有。 lxml文档使它看起来应该包含在string()
中,但我尝试了它,它也不起作用。我无法使用xpath和lxml找到任何方法。
所以,这是一种使用更多Python和更少xpath的方法:
import re
import lxml.etree as ET
rx = re.compile('.*\(.*\).*')
data = ET.parse('sample.xml')
for entry in data.iter('entry'):
for child in entry.xpath('.//*'):
if rx.match(child.text + child.tail):
# Your manipulations go here
print child
在任何一种情况下,一个令人愉快的副作用是这个正则表达式在雪中完全摇滚的好时光:.*\(.*\).*
。