【问题标题】:Editing Items in an XML File in Python在 Python 中编辑 XML 文件中的项目
【发布时间】:2018-09-25 21:11:28
【问题描述】:

我正在尝试从 .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 四个项目的值。

【问题讨论】:

  • 关于tree.findall("data"),你的xml中似乎没有任何&lt;data&gt;标签
  • xml 文件”是什么意思?这里没有 xml 文件。它只是一个 xml 字符串(可能会被修改)。你如何测试它是否改变了什么?您是否错过了 URL 中的最后一行:print(ET.tostring(tree))
  • 正确,没有 .xml 文件,因为我试图从 .csv 中的数据创建它们。我有一个 .xml 文件应该是什么样子的模板。但是,我需要弄清楚如何在 Python 中编辑 .xml 文件中的数据,然后才能执行此操作。最后的打印线也被应用了;这不是问题。

标签: python xml xml.etree


【解决方案1】:

我假设您阅读了 CSV 文件并提取了一组类似字典的记录,例如:

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 内容,您可以:

from xml.sax.saxutils import escape

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

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

结果是:

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

【讨论】:

  • 太棒了。比 xml.etree 更容易理解。非常感谢!
【解决方案2】:

我的偏好在于使用xmltodict。但是从您发布的链接来看,您似乎想在标签内而不是标签内制作 .find("filename") (正如评论中所述,它不存在于您的 xml 数据中) .

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 2017-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多