XMLTree 解析和打印

XMLTree Parsing and Printing

我开始学习 python3 正在讨论的事情之一是 XML我很难掌握的树(很可能是因为学习 python同时)

我想做的是输出一个更易于阅读的 XML 文件版本。

XML 文件:(儿童客户的数量没有限制 - 例如,我包括了两个)

<?xml version="1.0" encoding="UTF-8"?>
<customers>
     <customers>
          <number area_code="800" exch_code="225" sub_code="5288" />
          <address zip_code="90210" st_addr="9401 Sunset Blvd" />
          <nameText>First Choice</nameText>
     </customers>
     <customers>
          <number area_code="800" exch_code="867" sub_code="5309" /> 
          <address zip_code="60652" st_addr="5 Lake Shore Drive" />
          <nameText>Green Grass"</nameText>
     </customers>
</customers>

据我了解,XML tree 将这些行定义如下:

<root>
     <child>
          <element attribute...> 

其中第一个 xml 个文件 'customers' 是根,第二个 'customers' 是 'customers' 的子文件,'number'(或地址,或 nameText) 是元素。
话虽如此,这就是我开始感到困惑的地方。
如果我们取 <number area_code="800" exch_code="225" sub_code="5288" />
这是一个具有三个属性 area_code、exch_code 和 sub_code 但没有文本的元素。
如果我们取 <nameText>Green Grass"</nameText>
这是一个没有属性的元素,但包含文本(绿草)
我想看到的是这样的:

First Choice 
|--> Phone Number: 800-225-5288
|--> Address: 9401 Sunset Blvd, Zip Code: 90210 
Green Grass
|--> Phone Number: 800-867-5309
|--> Address: 5 Lake Shore Drive, Zip Code: 60652

我真的没有任何代码可以分享,但它是:

import xml.etree.ElementTree as ET
tree = ET.parse(my_files[0])
root = tree.getroot()
print(root.tag)
for child in root:
    print(child.tag,child.attrib)

它提供了以下输出(我相信第 1 行来自 print(root.tag))

customer
customer
{}
customer
{}

写完这些我的疑问:
1 - 我对树结构的解释是否正确?
2 - 如何区分 ElementTree 中的属性?
3 - How/what 在尝试生成所需的输出时,我应该考虑属性、标签和文件的其余部分吗?我可能想得太多了 XML 在混合中有多少更复杂的是造成这种情况所以我正在努力弄清楚如何做类似的事情来获得我在这里看到的输出:https://docs.python.org/3/library/xml.etree.elementtree.html#parsing-xml-with-namespaces 但是我的 xml 缺少命名空间。

我仍在努力学习,因此非常感谢任何额外的解释!

我一直试图通读以理解所有这些的资源:

1 - Is my interpretation of the tree structure correct?

ElementTree 解析器只知道两个实体:元素和 属性。所以当你说:

From what I understand, the XML tree defines these lines as the following:

<root>
     <child>
          <element attribute...> 

我有点困惑。您的 XML 文件 -- 或任何其他 XML 文件 -- 只是一个元素,可能具有零个或多个属性,并且可能 有零个或多个 children...等等。

2 - How do you differentiate between attributes in ElementTree?

这里的“区分”不清楚你指的是什么;你可以要求 按名称的元素。例如,下面的代码打印出 areacode 所有 <number> 元素的属性:

>>> from xml.etree import ElementTree as ET
>>> doc = ET.parse(open('data.xml'))
>>> doc.findall('.//number')
[<Element number at 0x7fdb8981e640>, <Element number at 0x7fdb8981e680>]
>>> for x in root.findall('.//number'):
...     print(x.get('area_code'))
...
800
800

如果愿意,您可以将元素的所有属性作为 Python 词典:

>>> number = doc.find('customers/number')
>>> attrs = dict(number.items())
>>> attrs
{'area_code': '800', 'exch_code': '225', 'sub_code': '5288'}

3 - How/what should I be considerate of in terms of the attributes, tags, and the rest of this file when trying to make the desired output?

该代码似乎主要包含您要查找的内容。正如你所说, 你没有使用命名空间,所以你不需要限定元素 带有命名空间名称的名称...也就是说,您可以改写 number {some/name/space}number.

这给了我们类似的东西:

from xml.etree import ElementTree as ET


with open('data.xml') as fd:
    doc = ET.parse(fd)


for customer in doc.findall('customers'):
    name = customer.find('nameText')
    number = customer.find('number')
    address = customer.find('address')
    print(name.text)
    print('|--> Address: {}, Zip Code: {}'.format(
        address.get('st_addr'), address.get('zip_code')))
    print('|--> Phone number: {}-{}-{}'.format(
        number.get('area_code'), number.get('exch_code'), number.get('sub_code')))

给定您的样本输入,这将产生:

First Choice
|--> Address: 9401 Sunset Blvd, Zip Code: 90210
|--> Phone number: 800-225-5288
Green Grass"
|--> Address: 5 Lake Shore Drive, Zip Code: 60652
|--> Phone number: 800-867-5309