使用Python编辑XML文件中的项目

时间:2018-09-25 21:11:29

标签: python xml xml.etree

我正在尝试从.csv文件中获取数据并为每一行创建单独的.xml文件。我已经将.csv读入了Pandas。我在努力的地方试图弄清楚如何在.xml文件中进行编辑。

我使用之前的答案作为尝试学习此内容的指南:

Link

将作者的解决方案应用于我的数据将如下所示:

data = """<annotation>
    <folder>VOC2007</folder>
    <filename>abc.jpg</filename>
    <object>
        <name>blah</name>
        <pose>unknown</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>0</xmin>
            <ymin>0</ymin>
            <xmax>0</xmax>
            <ymax>0</ymax>
        </bndbox>
    </object>
</annotation>
"""

然后我这样做:

tree = et.fromstring(data)

我要坚持的是下一部分。作者使用以下代码行编辑其文件:

for data in tree.findall("data"):
    name = data.attrib["name"]
    value = data.find("value")
    value.text = "[%s] %s" % (name, value.text)

我尝试像这样将其应用于我自己的

for data in tree.findall("data"):  
    filename = data.find("filename")
    filename.text = "001.jpg"

但是当我打印出来时,这似乎并没有改变任何东西。

print(et.tostring(tree))

我做错了什么,或者需要采取什么步骤将图像名称从“ abc.jpg”编辑为“ 001.jpg”?

还要尝试找出如何更改四个项xmin,ymin,xmax和ymax的值。

2 个答案:

答案 0 :(得分:1)

我假设您已读取CSV文件并提取了类似字典的记录的集合,例如:

julia> 2P
3.1415925750808533

您可以做的一件简单的事情是使用字符串模板来生成XML内容(因为它非常简单):

record = {
    'folder': "VOC2007",
    'filename': "abc.jpg",
    'name': "blah",
    'pose': "unknown",
    'truncated': "0",
    'difficult': "0",
    'xmin': "0",
    'ymin': "0",
    'xmax': "0",
    'ymax': "0",
}

要生成XML内容,您可以执行以下操作:

import textwrap

template = textwrap.dedent("""\
<annotation>
    <folder>{folder}</folder>
    <filename>{filename}</filename>
    <object>
        <name>{name}</name>
        <pose>{pose}</pose>
        <truncated>{truncated}</truncated>
        <difficult>{difficult}</difficult>
        <bndbox>
            <xmin>{xmin}</xmin>
            <ymin>{ymin}</ymin>
            <xmax>{xmax}</xmax>
            <ymax>{ymax}</ymax>
        </bndbox>
    </object>
</annotation>""")

函数xml.sax.saxutils.escape用于将“ <”,“>”和“&”转换为XML实体。

结果是:

from xml.sax.saxutils import escape

escaped = {k: escape(v) for k, v in record.items()}
data = template.format(**escaped)

答案 1 :(得分:0)

我更喜欢使用xmltodict。但是从您发布的链接来看,您似乎想从标记而不是标记中创建.find(“ filename”)(标记中也没有出现在标记中的标记)

也就是说,您的代码可以“最小”更改(例如,我不太了解ElementTree,无法说出最佳解决方案是什么),例如:

for annotation in tree.findall("annotation")
    filename = annotation.find("filename")
    filename.text = "001.jpg"