我需要编写python脚本来替换xml文件中某些单词的所有出现。我只需要替换标签中包含的禁止词。
这应该被替换:
<some_xml_tag>some text REPLACE_ME some text</some_xml_tag>
这不应该:
<some_xml_tag attr="REPLACE_ME">some text</some_xml_tag>
<REPLACE_ME>some text</REPLACE_ME>
我不是正则表达式专家,但它应该可能吗?
答案 0 :(得分:4)
使用 XML解析器。
使用lxml
库的示例。在这里,我们使用xpath()
搜索具有所需文本的节点,然后使用replace()
替换它:
import lxml.etree as ET
ban_word = 'REPLACE_ME'
replacement = 'HELLO'
data = """<root>
<some_xml_tag>REPLACE_ME</some_xml_tag>
<some_xml_tag attr="REPLACE_ME">some text</some_xml_tag>
<REPLACE_ME>some text</REPLACE_ME>
</root>
"""
root = ET.fromstring(data)
for item in root.xpath('//*[. = "%s"]' % ban_word):
item.text = item.text.replace(ban_word, replacement)
print ET.tostring(root)
打印:
<root>
<some_xml_tag>HELLO</some_xml_tag>
<some_xml_tag attr="REPLACE_ME">some text</some_xml_tag>
<REPLACE_ME>some text</REPLACE_ME>
</root>
注意:
xml.etree.ElementTree
无法处理此特定方法,因为它仅提供有限xpath
支持 答案 1 :(得分:3)
作为@ alexce的答案的扩展/替代,底线是:您仍然可以迭代所有子元素并替换循环中的所有单词:
import lxml.etree as ET
ban_words = ['REPLACE_ME', 'Some']
replacement = 'HELLO'
data = """<root>
<some_xml_tag>REPLACE_me</some_xml_tag>
<some_xml_tag attr="REPLACE_ME">Some text</some_xml_tag>
<REPLACE_ME>some text</REPLACE_ME>
</root>
"""
root = ET.fromstring(data)
# different approach using iter()
for node in root.iter():
for word in ban_words:
node.text = node.text.replace(word, replacement)
print ET.tostring(root)
结果将在列表中区分大小写:
<root>
<some_xml_tag>REPLACE_me</some_xml_tag>
<some_xml_tag attr="REPLACE_ME">HELLO text</some_xml_tag>
<REPLACE_ME>some text</REPLACE_ME>
</root>
如果您不想更换连接的单词,可以使用字典来匹配禁止的单词和替换,如下所示:
import lxml.etree as ET
ban = {'REPLACE_ME': 'HELLO', 'Some': 'HELLO'}
data = """<root>
<some_xml_tag>REPLACE_me</some_xml_tag>
<some_xml_tag attr="REPLACE_ME">REPLACE_ME Some text</some_xml_tag>
<REPLACE_ME>someSome Some SomeSOME text</REPLACE_ME>
</root>
"""
root = ET.fromstring(data)
# different approach using iter()
for node in root.iter():
txt = node.text.split(" ")
for i, t in enumerate(txt):
if ban.get(t):
txt[i] = ban.get(t)
node.text = ' '.join(txt)
print ET.tostring(root)
连接单词的结果不会被替换,只有完全匹配才会是:
<root>
<some_xml_tag>REPLACE_me</some_xml_tag>
<some_xml_tag attr="REPLACE_ME">HELLO HELLO text</some_xml_tag>
<REPLACE_ME>someSome HELLO SomeSOME text</REPLACE_ME>
</root>
答案 2 :(得分:1)
可以肯定......但是不要使用正则表达式,请尝试使用ElementTree:https://docs.python.org/2/library/xml.etree.elementtree.html
这将使查找/替换元素文本值更容易,而不是元素属性等。