【问题标题】:How to iterate through all XML Elements and apply logic to each Element's value with ElementTree for Python如何使用 Python 的 ElementTree 遍历所有 XML 元素并将逻辑应用于每个元素的值
【发布时间】:2013-03-18 00:44:09
【问题描述】:

我目前正在尝试将逻辑应用于 XML 文件中的元素值。具体来说,我正在尝试将所有值编码为 UTF-8,同时不触及任何元素名称/属性本身。

这里是示例 XML:

<?xml version="1.0"?>
<sd_1>
    <sd_2>
        <sd_3>\311 is a fancy kind of E</sd_3>
    </sd_2>
</sd_1>

目前我已经尝试了 3 种方法来实现这一点,但没有成功:

首先我尝试循环遍历每个元素,使用 .text 检索值并使用 .parse:

import xml.etree.ElementTree as ET

et = ET.parse('xml/test.xml')

for child in et.getroot():
    for core in child:
        core_value = str(core.text)
        core.text = core_value.encode('utf-8')

et.write('output.xml')

这会导致 XML 文件的文本 \311 没有正确更改,它只是保持原样。

接下来我用 cElementTree 尝试了 .iterparse 无济于事:

import xml.etree.cElementTree as etree

xml_file_path = 'xml/test.xml'
with open(xml_file_path) as xml_file:
    tree = etree.iterparse(xml_file) 
    for items in tree:
        for item in items:
            print item.text

etree.write('output1.xml')

这会导致:

 "...print item.text\n', "AttributeError: 'str' object has no attribute 'text'..."

不知道我在那里做错了什么,我看到了多个具有相同排列的示例,但是当我打印没有 .text 的元素时,我看到开头的字符串值为“end”的元组,我认为这是导致此方法出现问题的原因。

如何正确地遍历我的元素,而不指定元素名称,例如.findall(),将逻辑应用于每个元素中包含的值,以便当我将 xml 写入文件时,它会保存程序迭代元素值时所做的更改?

【问题讨论】:

    标签: python xml elementtree celementtree


    【解决方案1】:

    这是你要找的吗?

    import xml.etree.ElementTree as ET
    
    et = ET.parse('xml/test.xml')
    
    for child in et.getroot():
        for core in child:
            core_value = str(core.text)
            core.text = core_value.decode('unicode-escape')
    
    et.write('output.xml')
    

    【讨论】:

    • 哇,我不知道这存在!非常有帮助!用我明显较差的答案在 stackoverflow 上做的“正确”事情是什么?
    • @Square,如果字符在初始文档中实际上编码正确,您不只需要打开它,它们就会显示为unicode字符吗?
    • 我很抱歉这确实是我想要的。这对我来说是一个不熟悉的话题,当我将它加载到 PlanetPress 时,它正确地出现了。感谢gauden及时正确的回答,也感谢alex的帮助。
    【解决方案2】:

    这是一个有趣的问题。让我们关注您提出的第一种方法,因为这应该是解决此问题的完全好方法。当我一一打印出这些行时,我得到的是:

    >>> core_value
    '\\311 is a fancy kind of E'
    

    对我来说发生的事情是该字符被读取为文字“\”,必须对其进行转义才能按原样打印。如果我们将转义字符 (\\) 更改为非转义字符 (\),我们会得到以下结果:

    >>> cv = core_value.replace('\\311','\311')
    '\xc9 is a fancy kind of E'
    >>> print cv
    É is a fancy kind of E
    

    这里奇怪的是你不知道在原始文件中\311 什么时候“应该是”一个或四个字符。如果您知道这些都是一个字符,则可以根据此答案编写一些卑鄙的代码:

    Python Unicode, have unicode number in normal string, want to print unicode

    \ 之后的所有内容转换为正确的Unicode 字符并删除\

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-12
      • 2016-01-10
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多