python - 为什么 Elementtree 会迭代每个元素,即使它不是子元素?

标签 python xml elementtree

我创建了一个模型,用于使用 ElementTree 从 xml 文件中收集的数据创建对象。解析 xml 文件。我的项目有几千行代码,但我能够使用以下示例快速重新创建我的问题。

示例 XML 数据:

    <data>
       <country name="Liechtenstein">
          <rank>1</rank>
          <year>2008</year>
          <gdppc>141100</gdppc>
          <neighbor name="Austria" direction="E"/>
          <neighbor name="Switzerland" direction="W"/>
       </country>
       <country name="Singapore">
          <rank>4</rank>
          <year>2011</year>
          <gdppc>59900</gdppc>
          <neighbor name="Malaysia" direction="N"/>
       </country>
       <country name="Panama">
          <rank>68</rank>
          <year>2011</year>
          <gdppc>13600</gdppc>
          <neighbor name="Costa Rica" direction="W"/>
          <neighbor name="Colombia" direction="E"/>
       </country>
   </data>

型号:

class neighbor(object):
   name = ""
   direction = ""

class neighborList(object):
   neighbor = []

class country(object):
   name = ""
   rank = ""
   year = ""
   gdppc = ""
   neighborList = neighborList()

class countryList(object):
   country = []

class data(object):
   countryList = countryList()

解析器:

    from xml.etree import ElementTree as ET
    import countries_model as ctry

    def CountriesCrusher(filename):

        xmldoc = ET.parse(filename)
        element = xmldoc.getroot()

        _data = ctry
        _countryList = ctry.countryList()  

        for firstLevel in element.findall('country'):
            b = ctry.country()
            b.rank = firstLevel.find('rank').text
            b.year = firstLevel.find('year').text
            b.gdppc = firstLevel.find('gdppc').text
            b.neighborList = ctry.neighborList()

            for secondLevel in firstLevel.findall('neighbor'):
                c = ctry.neighbor
                c.direction = secondLevel.attrib.get('direction')
                c.name = secondLevel.attrib.get('name')
                b.neighborList.neighbor.append(c)

            _countryList.country.append(b)

        a = ctry.data()
        a.countryList = _countryList
        _data = a
        return _data

    ictry = CountriesCrusher('countries.xml')

在运行此命令之前,我希望如果我查看ictry.countryList.country,我会看到三个条目,如果我查看ictry.countryList.country[0],我会看到三个条目。 neighborList.neighbor 我会看到该国家/地区的两个邻居条目,但我看到的是整个 xml 文件中的所有五个邻居元素。为什么会出现这种情况??

最佳答案

您没有使用country类的实例属性。

像这样编写您的country类(以及所有其他类):

class country:
    def __init__(self):
        self.name = ""
        self.rank = ""
        self.year = ""
        self.gdppc = ""
        self.neighborList = neighborList()

现在,b = ctry.country() 将为您提供一个实例,其属性将与第二次调用 b = ctry.country() 解耦/分离。您当前的方法是 ctry.country 的所有实例共享相同的属性,因为它们是类属性,而不是实例属性。

了解更多关于class vs instance attributes here的信息.

关于python - 为什么 Elementtree 会迭代每个元素,即使它不是子元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34906972/

相关文章:

python - 在 python 中使用 ElementTree 将 xml 元素作为第一个子元素插入

python - 如何用iterparse来写?

python - 如何使用python中的elementtree处理xml文件中格式不正确的字符

python - 初始化dask系列

以字符串作为值类型的 Python defaultdict

python - Python 代码可以包含在 NetLogo 代码的主体中吗?

c++ - 在 C++ 中将特殊 ASCII 字符转换为 XML 兼容字符串

Python 和 SOAP

java - 使用属性获取元素

c# - 在数值中设置点而不是逗号