为 XML 数据提取的函数赋值时出现 AttributeError

AttributeError when assigning value to function for XML data extraction

我正在编写一个脚本,以从多个 XML 文件中提取信息,这些文件具有相同的结构,但在没有与标签相关的信息时缺少部分。实现此目的的最简单方法是使用 try/except,因此我没有获得 "AtributeError: 'NoneType' object has no atrribute 'find'",而是为异常中的对象分配了一个空字符串 ('')。像这样:

try:
   string1=root.find('value1').find('value2').find('value3').text
except:
   string1=''

问题是我想使用一个函数来压缩我的代码:

def extract(string):
    tempstr=''
    try:
        tempstr=string.replace("\n", "")
    except:
        if tempstr is None:
            tempstr=""
    return string

然后我试着这样称呼它:

string1=extract(root.find('value1').find('value2').find('value3').text)

并且 value2 或 value3 对于正在处理的 xml 不存在,即使我不在函数中使用变量使函数无用,我也会得到 AttributeError。

有没有办法让一个函数工作,也许有办法运行而不检查输入的值是否无效?

解法:

我混合使用了两个答案:

def extract(root, xpath):
    tempstr=''
    try:
        tempstr=root.findall(xpath)[0].text.replace("\n", "")
    except:
        tempstr=''#To avoid getting a Nonetype object
    return tempstr

您可以尝试类似的方法:

def extract(root, children_keys: list):
    target_object = root
    result_text = ''
    try:
        for child_key in children_keys:
            target_object = target_object.find(child_key)
        result_text = target_object.text
    except:
        pass

    return result_text

您将使用 for 循环更深入 XML 结构(children_keys - 由您预定义 XML 的嵌套键列表 - xml - 您的路径目的)。 如果错误会抛入该代码 - 你将得到 '' 作为结果。

示例 XML (source):

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>
    <y>Don't forget me this weekend!</y>
  </body>
</note>

示例:

import xml.etree.ElementTree as ET
tree = ET.parse('note.xml')
root = tree.getroot()
children_keys = ['body', 'y']
result_string = extract(root, children_keys)
print(result_string)

输出:

"Don't forget me this weekend!"

使用 XPATH 表达式

import xml.etree.ElementTree as ET

xml1 = '''<r><v1><v2><v3>a string</v3></v2></v1></r>'''
root = ET.fromstring(xml1)
v3 = root.findall('./v1/v2/v3')
if v3:
  print(v3[0].text)
else:
  print('v3 not found')


xml2 = '''<r><v1><v3>a string</v3></v1></r>'''
root = ET.fromstring(xml2)
v3 = root.findall('./v1/v2/v3')
if v3:
  print(v3[0].text)
else:
  print('v3 not found')

输出

a string
v3 not found