return python lxml text as string not single item list - 来自 xml

return python lxml text as string not single item list - from xml

使用微软 Books.xml https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms762271(v=vs.85)

第一个条目的示例。

<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
</catalog>

正在尝试从 ID 为奇数的 ID 中提取所有书名。抓取 id 和 title 作为 Key,字典中的值

到目前为止,除了所有标题 return 作为单个项目列表之外,我已经完成了这项工作。

import xml.etree.ElementTree as ET

tree = ET.parse('books.xml')
root = tree.getroot()

data = {}
for child in root.findall('book'):
    for k,v in child.items():
        for title in child.iter('title'):
            if int(v.split('k')[1]) % 2 != 0:
                if k not in data:
                    data[v] = []
                data[v].append(title.text)
            
print(data['bk101'])

输出

{'bk101': ["XML Developer's Guide"], 'bk103': ['Maeve Ascendant'], 'bk105': ['The Sundered Grail'], 'bk107': ['Splish Splash'], 'bk109': ['Paradox Lost'], 'bk111': ['MSXML3: A Comprehensive Guide']}

期望输出

{'bk101': "XML Developer's Guide", 'bk103': 'Maeve Ascendant', 'bk105': 'The Sundered Grail', 'bk107': 'Splish Splash', 'bk109': 'Paradox Lost', 'bk111': 'MSXML3: A Comprehensive Guide'}

如何 return 将标题作为文本而不是列表?

注意 我可以使用

从我的字典中提取它们作为文本
print(data['bk101'][0])

但是,我更希望将它们作为以后不提取的文本保存到字典中。

Edit 我意识到它是因为我在检查键是否存在时创建了一个列表作为默认值。但是,不能使用 None 类型作为占位符来避免列表副作用。

意识到我可能应该使用 fromkeys 作为这个答案 SO to initialising a dict with keys and empty value

但是我如何在循环中执行此操作?

如果您不希望每本书有多个 <title> 标签,则无需使用列表,您可以直接分配 title.text 的值而不是附加它。此外,当您知道自己特别需要 id 属性时,无需遍历 child.items()。如果有其他属性,它可能会导致问题,因为它们不会以相同的格式进行拆分。

假设每个 <book> 都有一个 id 和一个 <title> child(就像你的示例 XML 中的那样)的简化代码是如下:

for child in root.findall('book'):
    book_id = child.get('id')
    if int(book_id.split('k')[1]) % 2 != 0:
        data[book_id] = child.find('title').text

print(data)

这给出了输出:

{'bk101': "XML Developer's Guide", 'bk103': 'Maeve Ascendant', 'bk105': 'The Sundered Grail', 'bk107': 'Splish Splash', 'bk109': 'Paradox Lost', 'bk111': 'MSXML3: A Comprehensive Guide'}

如果 <title> 可能缺失,find() 可以 return None,因此需要额外的 if 条件。

如果您希望每个 <book> 有多个 <title> 标签,最好有一个列表并像您的问题一样使用 child.iter('title')。这也将隐式处理丢失的标题大小写,因为循环内的代码不会 运行.