如何从 XML 文件中自动获取相同类型的每个对象?

How to automatically get every object of the same type from an XML file?

我正在尝试将 XML 文件解析为 TXT 文件。这是我的 XML 文件的样子:

<annotation>
  <folder>training</folder>
  <filename>106310488.jpg</filename>
  <source>
    <database>synthetic initialization</database>
    <annotation>PASCAL VOC2007</annotation>
    <image>synthetic</image>
    <flickrid>none</flickrid>
  </source>
  <owner>
    <flickrid>none</flickrid>
    <name>none</name>
  </owner>
  <size>
    <width>1024</width>
    <height>681</height>
    <depth>3</depth>
  </size>
  <segmented>0</segmented>
  <object>
    <name>shell</name>
    <pose>Unspecified</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
      <xmin>234</xmin>
      <ymin>293</ymin>
      <xmax>281</xmax>
      <ymax>340</ymax>
    </bndbox>
 </object>
 <object>
    <name>shell</name>
    <pose>Unspecified</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
      <xmin>504</xmin>
      <ymin>302</ymin>
      <xmax>551</xmax>
      <ymax>349</ymax>
    </bndbox>
  </object>
  <object>
    <name>shell</name>
    <pose>Unspecified</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
      <xmin>776</xmin>
      <ymin>302</ymin>
      <xmax>823</xmax>
      <ymax>349</ymax>
    </bndbox>
  </object>
</annotation>

我感兴趣的信息在<object>内。我想获取 <name><bndbox> 中的所有内容。这些是数据集中对象的名称和边界框坐标。我不知道每个 XML 文件中有 <object> 个条目 <bndbox>,所以我想编写一个逻辑来获取所有这些条目。

到目前为止,我的逻辑所做的是仅获取并处理第一次出现的 <object><bndbox></bndbox></object>。如果 XML 文件中有任何其他边界框坐标,我的代码会直接跳过它。我不想要这个。这是我的代码:

for annotations_file in annotations_dir:

  annotations = []
  milliseconds = int(time() * 1000)

  doc = ET.parse('/content/darknet/logorec/openlogo/Annotations/' + annotations_file) # Parsing the XML file
  
  new_annotations_file_name = annotations_file.split('.')[0] # Getting the name of the XML file without the file extension
  
  canvas = cv2.imread('/content/darknet/logorec/openlogo/JPEGImages/' + new_annotations_file_name + '.jpg') # Get the entire image
  
  canvas_shape = canvas.shape # Get the dimensions of the image
  
  root = doc.getroot() # Gets the root of the XML file
  
  annotations_box = root[6][4] # Gets the bounding box coordinates from the XML file

  class_name = root[6][0] # Name of the object within the bounding box
  class_name = class_name.text # Getting the text value

  for ant in annotations_box:
    annotations.append(ant.text) # Appending every sindle bounding box coordinate to an empty list
  
  ''' These are my annotations calculations for the YOLO model'''
  logo_shape_w = int(annotations[2]) - int(annotations[0])
  logo_shape_h = int(annotations[3]) - int(annotations[1])

  x1 = int(annotations[0]) # x1 = xmin
  y1 = int(annotations[3]) # y1 = ymax

  x2 = x1 + logo_shape_w
  y2 = y1 + logo_shape_h

  w = x2 - x1
  h = y2 - y1

  center_x = x1 + (w/2)
  center_y = y1 + (h/2)

  x = center_x / canvas_shape[0]
  y = center_y / canvas_shape[1]

  width = w / canvas_shape[0]
  height = h / canvas_shape[1]
  '''---------------------------------------------------------'''

使用 xpath 解析 XML 可以迭代 objList 项目。仅显示第一项

>>> from lxml import etree                       
>>> tree = etree.parse('test.xml')                                                                                                              
>>> objList = tree.xpath('//object')
>>> bnd = objList[0].xpath('name | bndbox/*')
>>> for e in bnd:
...     e.text
... 
'shell'
'234'
'293'
'281'
'340'

迭代所有对象

>>> for obj in objList:
...      bnd = obj.xpath('name | bndbox/*')
...      for e in bnd:
...          e.text
... 
'shell'
'234'
'293'
'281'
'340'
'shell'
'504'
'302'
'551'
'349'
'shell'
'776'
'302'
'823'