如何迭代所有XML元素并使用ElementTree for Python将逻辑应用于每个Element的值

时间:2013-03-27 19:01:39

标签: python xml elementtree celementtree

我目前正在尝试将逻辑应用于XML文件中的Element值。具体来说,我试图将所有值编码为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写入文件时,它会保存程序迭代元素值时所做的更改吗?

2 个答案:

答案 0 :(得分:4)

这是你在找什么?

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')

答案 1 :(得分:0)

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

>>> 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字符并删除\