Python を使用して XML 形式の注釈ファイルを作成、追加、変更する

深層学習のターゲット検出で使用されるデータ セットでは、xml 形式のアノテーション ファイルがよく使用されます (たとえば、VOC 形式のデータ セットで使用されるアノテーション ファイルは xml 形式です)。XML 注釈ファイルを自分で作成する場合、または他のタイプの注釈ファイル (txt、json など) を XML 形式に変換する場合、この知識を理解する必要があります。

以下に、lxml の助けを借りて Python を使用して XML タイプのファイルの関数を作成、追加、および変更するための実装コードをリストします。

1. XML形式でアノテーションファイルを作成する

以下に、XML 形式ファイルを作成するコードと、コードの実行後に生成される XML ファイルのコンテンツ レンダリングを示します。ここでは、XML ファイルを作成し、ルート ノードを設定し、ルート ノードに複数の子ノードを追加し、ノードに名前を付けるだけです。 、ノードに含まれる te​​xt テキスト情報を設定します。

コードは以下のように表示されます。

from lxml.etree import Element, tostring, parse
from lxml.etree import SubElement as subElement
def xml_construct(save_path,folder,filename,path,width=800,height=600,depth = 3,segmented=0):
    default_text = 'default'
    node_root = Element('annotation')  # 根节点

    node_folder = subElement(node_root, 'folder')  # 在节点下添加名为'folder'的子节点
    node_folder.text = folder  # 设定节点的文字

    node_filename = subElement(node_root, 'filename')
    node_filename.text = filename

    node_path = subElement(node_root, 'path')
    node_path.text = path

    node_size = subElement(node_root, 'size')
    node_size_width = subElement(node_size, 'width')
    node_size_width.text = '%s' % int(width)
    node_size_height = subElement(node_size, 'height')
    node_size_height.text = '%s' % int(height)
    node_size_depth = subElement(node_size, 'depth')
    node_size_depth.text = '%s' % int(depth)

    node_segmented = subElement(node_root, 'segmented')
    node_segmented.text = '%s' % int(segmented)

    xml = tostring(node_root, pretty_print=True) #将上面设定的一串节点信息导出
    with open(save_path,'wb') as f: #将节点信息写入到文件路径save_path中
        f.write(xml)

    return

#----------调用上面所写的函数进行试验,创建名为test.xml的xml文件----------
xml_construct('test.xml','test','test','test',width=1600,height=1200,)

上記のコードを実行した結果は次のようになります。

2. 既存の XML ファイルにノードを追加する

ここでは、既存の xml ファイルにノードを追加し、前の手順で生成された test.xml でそれを変更する方法を示します。

コードは以下のように表示されます。
 

from lxml.etree import Element, tostring, parse
from lxml.etree import SubElement as subElement
def xml_add_object(xml_path,name,id,xmin,ymin,xmax,ymax,pose = 'Unspecified',truncated=0,difficult=0):
    tree = parse(xml_path)  # 读取xml文件
    node_root = tree.getroot()  # 找到xml文件的根节点
    node_object = subElement(node_root, 'object')  #在根节点node_root下面添加名为'object'的子节点
    node_object_name = subElement(node_object, 'name') #在根节点node_root的子节点object下面继续添加子节点object的子节点'name'
    node_object_name.text = name #设定该节点的文本text信息
    node_object_id = subElement(node_object, 'id')
    node_object_id.text = '%s' % int(id)
    node_object_pose = subElement(node_object, 'pose')
    node_object_pose.text = pose
    node_object_truncated = subElement(node_object, 'truncated')
    node_object_truncated.text = '%s' % int(truncated)
    node_object_difficult = subElement(node_object, 'difficult')
    node_object_difficult.text = '%s' % int(difficult)
    # object坐标
    node_bndbox = subElement(node_object, 'bndbox')
    node_xmin = subElement(node_bndbox, 'xmin')
    node_xmin.text = '%s' % int(xmin)
    node_ymin = subElement(node_bndbox, 'ymin')
    node_ymin.text = '%s' % int(ymin)
    node_xmax = subElement(node_bndbox, 'xmax')
    node_xmax.text = '%s' % int(xmax)
    node_ymax = subElement(node_bndbox, 'ymax')
    node_ymax.text = '%s' % int(ymax)

    xml = tostring(node_root, pretty_print=True) #将修改后的xml节点信息导出

    with open(xml_path,'wb') as f: #将修改后的xml节点信息覆盖掉修改前的
        f.write(xml)

    return

#----------试验,在test.xml中进行添加节点操作----------
xml_add_object(xml_path='test.xml',name='test_name',id=999,xmin=1,ymin=2,xmax=3,ymax=4,)

上記のコードを実行すると、元の test.xml ファイルが対応する子ノードとともに追加され、その効果は次のようになります。

3. 既存の XML ファイル内の特定のノードの情報を変更します

XML ファイル内の特定のノード情報のみを変更したい場合は、いくつかのコード操作を実行できます (ここでも、上記の test.xml ファイルを操作オブジェクトとして使用し、サイズ ノードの下の幅と高さのノード情報を次のように変更します)変更):

from lxml.etree import Element, tostring, parse
from lxml.etree import SubElement as subElement
def modify_size(xml_path,size_width=800,size_height=600):
    tree = parse(xml_path)
    width = tree.xpath('//width')#这里返回的width是一个包含所有名称中带有"width"的节点的列表
    for width_i in width:
        width_i.text = '%s' % int(size_width) #这里直接写width_i.text = size_width会报错

    height = tree.xpath('//height')
    for height_i in height:
        height_i.text = '%s' % int(size_height)

    node_root = tree.getroot()
    xml = tostring(node_root, pretty_print=True)
    with open(xml_path,'wb') as f:
        f.write(xml)

    return

#----------试验----------
#以上面的test.xml文件为操作对象,将其中的size节点下的width和height节点信息进行修改
modify_size('test.xml',size_width=800,size_height=600)

効果は次のとおりです。

 

おすすめ

転載: blog.csdn.net/qq_40641713/article/details/127537245