如何编辑XML文件并保存在新文件中?

时间:2019-09-18 16:39:47

标签: python xml python-3.x

我正在研究数据扩充。我想编辑一个XML文件并将其保存到新的XML文件中。这是原始XML文件的示例:

   <object>
       <name>car</name>
       <pose>Unspecified</pose>
       <truncated>0</truncated>
       <difficult>0</difficult>
       <bndbox>
         <xmin>670</xmin>
         <ymin>108</ymin>
         <xmax>947</xmax>
         <ymax>265</ymax>
       </bndbox>
     </object>
     <object>
       <name>number_plate</name>
       <pose>Unspecified</pose>
       <truncated>0</truncated>
       <difficult>0</difficult>
       <bndbox>
         <xmin>808</xmin>
         <ymin>210</ymin>
         <xmax>865</xmax>
         <ymax>232</ymax>
       </bndbox>
     </object>

此外,我想将xmin的值更改为xmin + 100,将xmax的值更改为xmax + 100。 我尝试了以下代码,该代码不会产生任何结果:

   from PIL import Image
   import numpy as np
   import os
   import xml.etree.ElementTree as ET

   filename = ("/home/omarubuntu/PFEomar/depassement_stationnemen/conv-video_frame/Annotationflip_xml/")
   for image_name in os.listdir(filename):
       tree = ET.parse(filename+image_name)
       objs = tree.findall('object')
       for ix, obj in enumerate(objs):
           bbox = obj.find('bndbox')
           new_x1 = 1280-int(bbox.find('xmin').text)
           nex_y1 = int(bbox.find('ymin').text)
           new_x2 = 1280 - int(bbox.find('xmax').text)
           new_y2 = int(bbox.find('ymax').text)
             tree.write("/home/omarubuntu/PFEomar/depassement_stationnement/conv-video_frame/Annotationflip1_xml/"+image_name)

2 个答案:

答案 0 :(得分:1)

您从tree获得了价值并对其进行了更改,但您并没有将其放回tree-即。

xmin = bbox.find('xmin')
xmin.text = str(1280 - int(xmin.text))

您并没有使用文件的新名称来保存它。


这是您的更改代码,但我没有运行

import os
import xml.etree.ElementTree as ET

dirname = "/home/omarubuntu/PFEomar/depassement_stationnemen/conv-video_frame/Annotationflip_xml/"

for image_name in os.listdir(dirname):
    fullpath = os.path.join(dirname, image_name)

    tree = ET.parse(fullpath)

    objs = tree.findall('object')

    for ix, obj in enumerate(objs):
        bbox = obj.find('bndbox')

        xmin = bbox.find('xmin')
        xmin.text = str(1280 - int(xmin.text))

        xmax = bbox.find('xmax')
        xmax.text = str(1280 - int(xmax.text))

    new_fullpath = ospath.join(dirname, 'new_'+image_name)
    tree.write(new_fullpath)

这是我用来测试的代码,它显示带有新值的xml

import xml.etree.ElementTree as ET

text = '''<root>
     <object>
       <name>car</name>
       <pose>Unspecified</pose>
       <truncated>0</truncated>
       <difficult>0</difficult>
       <bndbox>
         <xmin>670</xmin>
         <ymin>108</ymin>
         <xmax>947</xmax>
         <ymax>265</ymax>
       </bndbox>
     </object>
     <object>
       <name>number_plate</name>
       <pose>Unspecified</pose>
       <truncated>0</truncated>
       <difficult>0</difficult>
       <bndbox>
         <xmin>808</xmin>
         <ymin>210</ymin>
         <xmax>865</xmax>
         <ymax>232</ymax>
       </bndbox>
     </object>
</root>'''


tree = ET.fromstring(text)

objs = tree.findall('object')

for ix, obj in enumerate(objs):
    bbox = obj.find('bndbox')

    xmin = bbox.find('xmin')
    xmin.text = str(1280 - int(xmin.text))

    xmax = bbox.find('xmax')
    xmax.text = str(1280 - int(xmax.text))

print(ET.tostring(tree).decode())

答案 1 :(得分:1)

如果只需要向xmin / xmax元素添加100,则可以使用xslt身份转换模式并让libxml承担繁重的工作:

from lxml import etree

xsl = etree.XML('''
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>

    <!-- match xmin and xmax elements -->
    <xsl:template match="xmin|xmax">
        <xsl:copy>
            <!-- add 100 to the value of the current node -->
            <xsl:value-of select=". + 100" />
        </xsl:copy>
    </xsl:template>

    <!-- recursively copy the rest of the xml document -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
''')

transform = etree.XSLT(xsl)
with open("original.xml") as f:
    print(transform(etree.parse(f)), end='')

使用diff进行测试:

diff original.xml <(./augmentation.py)
0a1
> <?xml version="1.0"?>
8c9
<           <xmin>670</xmin>
---
>           <xmin>770</xmin>
10c11
<           <xmax>947</xmax>
---
>           <xmax>1047</xmax>
20c21
<           <xmin>808</xmin>
---
>           <xmin>908</xmin>
22c23
<           <xmax>865</xmax>
---
>           <xmax>965</xmax>

如果样式表存储在文件extensionation.xsl中,则可以使用libxml实用程序xsltproc获得相同的结果:

diff original.xml <(xsltproc augmentation.xsl original.xml)