NoneType'对象没有属性'data

1 投票
4 回答
11231 浏览
提问于 2025-04-15 23:34

我正在向我的服务器发送一个SOAP请求,并收到了响应。下面是响应字符串的一个示例:

<?xml version = '1.0' ?>
<env:Envelope xmlns:env=http:////www.w3.org/2003/05/soap-envelop
.
..
..
<env:Body>
    <epas:get-all-config-resp xmlns:epas="urn:organization:epas:soap"> ^M
...
...
<epas:property name="Tom">12</epas:property>
> 
> <epas:property name="Alice">34</epas:property>
> 
> <epas:property name="John">56</epas:property>
> 
> <epas:property name="Danial">78</epas:property>
> 
> <epas:property name="George">90</epas:property>
> 
> <epas:property name="Luise">11</epas:property>

...
^M
</env:Body?
</env:Envelop>

我注意到在响应的内容中,有一个额外的字符显示为“^M”。我不确定这是否会造成问题。请注意显示的^M!

当我尝试解析从服务器返回的字符串,以获取名称和值时,使用了以下代码示例:

elements = minidom.parseString(xmldoc).getElementsByTagName("property")      
myDict = {}
for element in elements:
  myDict[element.getAttribute('name')] = element.firstChild.data

但是,我遇到了这个错误:'NoneType'对象没有'data'属性。可能这与xml响应中的“^M”有关!

任何想法或评论都非常感谢,

谢谢

4 个回答

0

这个错误提示是说,你的某个元素的第一个子元素(firstChild)被设置成了空值(None),所以当你试图访问它的 .data 时就会出错。

我猜问题出在那个结尾的 ^M 上。这个 ^M 产生的元素是无效的,因此它没有第一个子元素。

你可以通过在提取 .data 之前,先检查一下 firstChild 是否等于空值(None)来避免这个问题。

1

你可以筛选出那些第一个子元素是空的元素。看起来这确实和 ^M 有关系,它可能被转变成了一个文本节点对象,也就是一个没有任何内容的空白节点。

elements = minidom.parseString(xmldoc).getElementsByTagName("property")      
myDict = {}
for element in elements:
    if element.firstChild:
        myDict[element.getAttribute('name')] = element.firstChild.data
3

为了让内容更清楚,我做了一些编辑,并建议你检查一下是否有空的元素。

看起来,使用getElementsByTagName返回的一些元素没有firstChild。这种情况发生在元素是空的时候,比如:

<epas:property name="Empty"></epas:property>

当minidom遇到这种情况时,它会把"element.firstChild"设置为None。这很可能就是你遇到的问题。

除此之外,光凭一小段XML(而且还是有问题的)很难确切知道发生了什么,但你可以尝试捕获异常,并检查一下相关的元素:

for element in elements:
    try:
        myDict[element.getAttribute('name')] = element.firstChild.data
    except AttributeError:
        print element, element.firstChild

或者,不仅仅是打印这个元素,你可以调用调试器(import pdb; pdb.set_trace())。这样你就能看到这个元素,并理解为什么它会给你带来麻烦。

顺便提一下,"^M"只是Windows风格的换行符。我调整了你粘贴的XML片段以便在本地测试,"^M"根本没有影响,minidom会处理这个问题。

所以,检查一下是否有空的元素,或者使用我建议的try/except。如果你还是搞不清楚发生了什么,可以把完整的XML字符串粘贴到http://pastebin.com/上,我可能能帮你。

另外,关于相关的内容:一旦你解决了这个问题,你可以用列表推导式来构建字典:

myDict = dict((element.getAttribute('name'), element.firstChild.data) for element in elements)

如果你确定是空元素的问题,你可以这样跳过它们:

myDict = dict((element.getAttribute('name'), element.firstChild.data) for element in elements if element.firstChild is not None)

撰写回答