替换XML文件中的单词

时间:2015-01-09 21:30:43

标签: python regex xml replace xml-parsing

我需要编写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>

我不是正则表达式专家,但它应该可能吗?

3 个答案:

答案 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支持
  • 正如@tdelaney在评论中指出的那样,如果你有一个要替换的单词列表,那么简单地遍历所有节点并在必要时替换文本可能是个好主意

答案 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

这将使查找/替换元素文本值更容易,而不是元素属性等。