使用json解析XML会引发ValueError

时间:2015-06-05 14:39:42

标签: python json xml xml-parsing

我尝试使用xml ElementTree和json

解析XML文件
timedelta

XML文件:

from xml.etree import ElementTree as et
import json

def parse_file(file_name):
    tree = et.ElementTree()
    npcs = {}
    for npc in tree.parse(file_name):
        quests = []
        for quest in npc:
            quest_name = quest.attrib['name']
            stages = []
            for i, stage in enumerate(quest):
                next_stage, choice, npc_condition = None, None, None
                for key, val in stage.attrib.items():
                    val = json.loads(val)
                    if key == 'choices':
                        choice = val
                    elif key == 'next_stage':
                        next_stage = val
                    elif key == 'ncp_condition':
                        npc_condition = {stage.attrib['npc_name']: val}
                stages.append([i, next_stage, choice, npc_condition])
            quests.append( {quest_name:stages})
        npcs[npc.attrib['name']] = quests
    return npcs

但我在这方面遇到了麻烦:

<?xml version="1.0" encoding="utf-8"?>
<npcs>
    <npc name="NPC NAME">
        <quest0 name="Quest Name here">
            <stage0 choices='{"Option1":1, "Option1":2}'>
                <text>text1</text> 
            </stage0>
            <stage1 next_stage="[3,4]">
                <text>text2</text> 
            </stage1>
            <stage3 npc_name="other_npc_name" ncp_condition='{"some_condition":false}' next_stage="[3, 4]">
                <text>text3</text>
            </stage3>
        </quest0>
    </npc>
</npcs>

回溯:

<stage3 npc_name="other_npc_name" ncp_condition='{"some_condition":false}' next_stage="[3, 4]">

Traceback (most recent call last): File "C:/.../test2.py", line 28, in <module> parse_file('quests.xml') File "C:/.../test2.py", line 15, in parse_file val = json.loads(val) File "C:\Python27\lib\json\__init__.py", line 338, in loads return _default_decoder.decode(s) File "C:\Python27\lib\json\decoder.py", line 366, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "C:\Python27\lib\json\decoder.py", line 384, in raw_decode raise ValueError("No JSON object could be decoded") ValueError: No JSON object could be decoded val = json.loads(val)时,它会在key="npc_name"行中引发此错误。

这有什么不对?它在val="other_npc_name"时没有引发任何错误,但在name="some string"时却发生错误。

我注意到,如果我将npc_name="some string"更改为"other_npc_name",它就不会抱怨,但这对我来说似乎有些骇人听闻

1 个答案:

答案 0 :(得分:1)

JSON是一种存储数据结构的方法 - 因此它只能解码所述数据结构。

当你试图让JSON解码这样的东西时:

  

other_npc_name

JSON无法将此与任何有效数据类型匹配。但是,如果它用引号括起来:

  

“other_npc_name”

JSON将此识别为String(根据JSON规范,即字符串的定义方式)。

这就是你的剧本中发生的事情:

import json
print json.loads("other_npc_name") #throws error
print json.loads('"other_npc_name"') #returns "other_npc_name" as a Unicode string

因此,以这种方式包装字符串似乎是“hackish”,但是,这实际上是JSON解码它的唯一方法。

一个可能的建议是,如果XML中的npc_name属性始终是字符串,则将其作为字符串拉出,而不是尝试将其解码为JSON对象。