使用不同长度的数组遍历 XML 数据

原文标题Iterate through XML data with arrays of different lengths

我有一个 XML 文件,其中包含摄影测量中使用的连接点。我正在尝试使用 Python 来提取已用于每个连接点的纬度、经度、高度和图像 ID。

XML数据如下

<?xml version="1.0" encoding="utf-8"?>
<TiePoints>
    <TiePoint>
        <Position>
            <x>127.915511902581</x>
            <y>-33.4353126218486</y>
            <z>16.4129273099825</z>
        </Position>
        <Color>
            <Red>0.474509803921569</Red>
            <Green>0.403921568627451</Green>
            <Blue>0.325490196078431</Blue>
        </Color>
        <Measurement>
            <PhotoId>2</PhotoId>
            <x>3693.80004882812</x>
            <y>925.170166015625</y>
        </Measurement>
        <Measurement>
            <PhotoId>3</PhotoId>
            <x>3671.1689453125</x>
            <y>2261.18017578125</y>
        </Measurement>
        <Measurement>
            <PhotoId>22</PhotoId>
            <x>3706.51635742188</x>
            <y>1812.31091308594</y>
        </Measurement>
    </TiePoint>
    <TiePoint>
        <Position>
            <x>127.915470841975</x>
            <y>-33.4353080715225</y>
            <z>16.2808672133833</z>
        </Position>
        <Color>
            <Red>0.63921568627451</Red>
            <Green>0.572549019607843</Green>
            <Blue>0.466666666666667</Blue>
        </Color>
        <Measurement>
            <PhotoId>2</PhotoId>
            <x>3184.81469726562</x>
            <y>928.787292480469</y>
        </Measurement>
        <Measurement>
            <PhotoId>3</PhotoId>
            <x>3155.33715820312</x>
            <y>2289.67504882812</y>
        </Measurement>
        <Measurement>
            <PhotoId>22</PhotoId>
            <x>4187.51220703125</x>
            <y>1816.5751953125</y>
        </Measurement>
        <Measurement>
            <PhotoId>518</PhotoId>
            <x>2024.55029296875</x>
            <y>959.028137207031</y>
        </Measurement>
        <Measurement>
            <PhotoId>519</PhotoId>
            <x>1895.59228515625</x>
            <y>1790.13635253906</y>
        </Measurement>
    </TiePoint>

我面临的问题是每个连接点使用的照片数量不同(从 3 到 6+),由 PhotoID 表示。我已经把我正在使用的代码放在下面。

当我运行下面的代码时,我得到一个 TypeError: ‘NoneType’ object is not iterable。我是使用 Python 的新手,并且知道我使用 for 循环的方式可能不正确,但我现在不知道该怎么做。

任何帮助将不胜感激!

import pandas as pd
import numpy as np
import ntpath as nt

import xml.etree.cElementTree as et
import pandas as pd
tree=et.parse('TiePoints.xml')
root=tree.getroot()

TiePoint = []
PosX = []
PosY = []
PosZ = []
PhotoId1 = []
PhotoId2 = []
PhotoId3 = []
PhotoId4 = []
PhotoId5 = []
n = -1
i = 1

for tiepoint in root.findall("TiePoint"):
    n = n + i
    TiePoint.append(n)
    for posx in tiepoint.findall(".//Position/x"):
        PosX.append(posx.text)
    for posy in tiepoint.findall(".//Position/y"):
        PosY.append(posy.text)
    for posz in tiepoint.findall(".//Position/z"):
        PosZ.append(posz.text)
    for photoid1 in tiepoint.find(".//Measurement[1]/PhotoId[1]"):
        PhotoId1.append(photoid1.text)
    for photoid2 in tiepoint.find(".//Measurement[2]/PhotoId[1]"):
        PhotoId2.append(photoid2.text)  
    for photoid3 in tiepoint.find(".//Measurement[3]/PhotoId[1]"):
        PhotoId3.append(photoid3.text) 
    for photoid4 in tiepoint.find(".//Measurement[4]/PhotoId[1]"):
        PhotoId4.append(photoid4.text)

TiePoints_df = pd.DataFrame(list(zip(TiePoint,PosX,PosY,PosZ,PhotoId1,PhotoId2,PhotoId3,PhotoId4,PhotoId5)),columns=['Tie Point','Pos X','Pos Y','Pos Z','PhotoID 1','PhotoID 2','PhotoID 3','PhotoID 4','PhotoID 5'])

TiePoints_df.head()

TiePoints_df.to_csv("tiepoints-converted.csv")

原文链接:https://stackoverflow.com//questions/71476572/iterate-through-xml-data-with-arrays-of-different-lengths

回复

我来回复
  • Amirhossein Kiani的头像
    Amirhossein Kiani 评论

    问题是,第一个TiePoint标签有三个Measurement标签。所以在调用第四个Measurement标签时需要更加小心。在这种情况下,我决定将您的代码编辑为以下内容:

    import pandas as pd
    import numpy as np
    import ntpath as nt
    
    import xml.etree.cElementTree as et
    import pandas as pd
    tree=et.parse('TiePoints.xml')
    root=tree.getroot()
    
    TiePoint = []
    PosX = []
    PosY = []
    PosZ = []
    PhotoId1 = []
    PhotoId2 = []
    PhotoId3 = []
    PhotoId4 = []
    PhotoId5 = []
    n = -1
    i = 1
    
    for tiepoint in root.findall("TiePoint"):
        n = n + i
        TiePoint.append(n)
        for posx in tiepoint.findall(".//Position/x"):
            PosX.append(posx.text)
        for posy in tiepoint.findall(".//Position/y"):
            PosY.append(posy.text)
        for posz in tiepoint.findall(".//Position/z"):
            PosZ.append(posz.text)
        for photoid1 in tiepoint.find(".//Measurement[1]/PhotoId[1]"):
            PhotoId1.append(photoid1.text)
        for photoid2 in tiepoint.find(".//Measurement[2]/PhotoId[1]"):
            PhotoId2.append(photoid2.text)  
        for photoid3 in tiepoint.find(".//Measurement[3]/PhotoId[1]"):
            PhotoId3.append(photoid3.text) 
        try:
          for photoid4 in tiepoint.find(".//Measurement[4]/PhotoId[1]"):
              PhotoId4.append(photoid4.text)
        except:
          PhotoId4.append(None)
    
    TiePoints_df = pd.DataFrame(list(zip(TiePoint,PosX,PosY,PosZ,PhotoId1,PhotoId2,PhotoId3,PhotoId4,PhotoId5)),columns=['Tie Point','Pos X','Pos Y','Pos Z','PhotoID 1','PhotoID 2','PhotoID 3','PhotoID 4','PhotoID 5'])
    
    TiePoints_df.head()
    
    TiePoints_df.to_csv("tiepoints-converted.csv")
    
    2年前 0条评论