将XML解析到Python/Django列表字典中
我在用python解析xml时遇到了一个小问题。我正在努力使我的字典看起来像下面这样将XML解析到Python/Django列表字典中,python,xml,django,dictionary,Python,Xml,Django,Dictionary,我在用python解析xml时遇到了一个小问题。我正在努力使我的字典看起来像下面这样 listDict = [{'name':'Sales','id':'1','position':'1','order_by_type':'True','order_by_asc':'True;}, {'name':'Information','id':'2','position':'1','order_by_type':'True','order_by_asc':'True;}] 我认为从xml字符串中提取数
listDict = [{'name':'Sales','id':'1','position':'1','order_by_type':'True','order_by_asc':'True;}, {'name':'Information','id':'2','position':'1','order_by_type':'True','order_by_asc':'True;}]
我认为从xml字符串中提取数据后的循环是错误的
xml_data = ElementTree.fromstring(self.data)
# Lets grab all the base cats info and add them to a dict containing a list
base_cats = xml_data.findall('./BaseCategory/Name')
base_cats_id = xml_data.findall('./BaseCategory/base_id')
base_postion = xml_data.findall('./BaseCategory/position')
base_order_by_type = xml_data.findall('./BaseCategory/order_by_type')
base_order_by_asc = xml_data.findall('./BaseCategory/order_by_asc')
# store all information into lists
base_cat = [t.text for t in base_cats]
base_id = [t.text for t in base_cats_id]
base_p = [t.text for t in base_postion]
base_obt = [t.text for t in base_order_by_type]
base_asc = [t.text for t in base_order_by_asc]
base_dict = defaultdict(list)
# lets put everything in the list into a dictionary
for base in range(len(base_cat)): # for each base in base_cat loop
base_dict[base].append(base_cat[base])
base_dict[base].append(base_id[base])
base_dict[base].append(base_p[base])
base_dict[base].append(base_obt[base])
base_dict[base].append(base_asc[base])
这将产生以下结果
instance = {0: ['Sales 2', '1', '10', 'True', 'True'], 1: ['Information 2', '2', '20', 'True', 'True'], 2: ['Listing 2', '3', '30', 'True', 'True'], 3: ['Information', '4', '40', 'True', 'True'], 4: ['Land', '5', '50', 'True', 'True'], 5: ['&', '6', '60', 'True', 'True'], 6: ['Tax', '7', '70', 'True', 'True'], 7: ['Construction', '9', '90', 'True', 'True'], 8: ['Interior/Utilites', '10', '100', 'True', 'True'], 9: ['HOA/Community', '11', '110', 'True', 'True'], 10: ['Remarks', '12', '120', 'True', 'True'], 11: ['Exterior', '8', '80', 'True', 'True']})
我的最终目标是能够在django模板上执行以下操作
{%for item in instance%}
{{ item.name }}
{% endfor %}
任何关于我可能有什么问题的帮助都会有很大帮助。提前谢谢你的帮助
编辑:
正如我所问的,这里是我所拥有的xml
<?xml version="1.0" ?>
<FormInstance>
<BaseCategory>
<Name>Sales</Name>
<base_id>1</base_id>
<position>10</position>
<order_by_type>True</order_by_type>
<order_by_asc>True</order_by_asc>
</BaseCategory>
<BaseCategory>
<Name>Information</Name>
<base_id>2</base_id>
<position>20</position>
<order_by_type>True</order_by_type>
<order_by_asc>True</order_by_asc>
<MainCategory>
<main_id>1</main_id>
<Name>Address 3</Name>
<is_visible>True</is_visible>
<position>10</position>
<order_by_type>True</order_by_type>
<order_by_asc>True</order_by_asc>
<SubCategory>
<sub_id>1</sub_id>
<Name>Street Number 2</Name>
<sub_library_id>StreetNumber</sub_library_id>
<field_display_type>[u'input']</field_display_type>
<field_type>[u'varchar']</field_type>
<is_active>True</is_active>
<is_required>True</is_required>
<help_text>Street Number</help_text>
<main_category>1</main_category>
<is_visible>True</is_visible>
<position>10</position>
<order_by_type>True</order_by_type>
<order_by_asc>True</order_by_asc>
<show_seller>True</show_seller>
<Enumerations>
<enum_id>4</enum_id>
<Name>Test Enum</Name>
<library_id>test enum</library_id>
<is_active>True</is_active>
<sub_category>1</sub_category>
<is_visible>True</is_visible>
<position>10</position>
<order_by_type>True</order_by_type>
<order_by_asc>True</order_by_asc>
</Enumerations>
</SubCategory>
</MainCategory>
</BaseCategory>
</FormInstance>
销售额
1.
10
真的
真的
问询处
2.
20
真的
真的
1.
地址3
真的
10
真的
真的
1.
第二街
街道号码
[u'输入']
[u'varchar']
真的
真的
街道号码
1.
真的
10
真的
真的
真的
4.
测试枚举
测试枚举
真的
1.
真的
10
真的
真的
因此,对于我在预期结果中收集到的信息,您似乎只想获得有关严格属于基本类别的节点的信息,对吗?在编辑中提供的XML中,您有两个
您应该将XML视为节点树。在本例中,您有如下内容:
FormInstance # this is the root
/ \
/ \
BaseCategory BaseCategory
(name:Sales) (name:Information)
\
\
MainCategory
(name:Address 3)
\
\
Subcategory
(name:Street Number 2)
import pprint
from xml.etree import ElementTree
with open("sample_xml.xml", 'r') as f:
data = f.read()
xml_data = ElementTree.fromstring(data)
base_categories = xml_data.findall("./BaseCategory")
print("Found %s base_categories." % len(base_categories))
list_dict = []
for base_category in base_categories:
list_dict.append({
"name": base_category.find("Name").text,
"id": int(base_category.find("base_id").text),
"position": int(base_category.find("position").text),
"order_by_type": (True if base_category.find("order_by_type").text.lower() == "true"
else False),
"order_by_asc": (True if base_category.find("order_by_asc").text.lower() == "true"
else False),
})
print("list_dict=%s" % (pprint.pformat(list_dict)))
但是您只需要BaseCategory
元素中的信息,对吗
您可以将自己定位在根目录中(这…嗯…无论如何都是这样)迭代其BaseCategory
节点,从这些BaseCategory
节点中获取所需的项,并将它们放入字典列表中
比如:
FormInstance # this is the root
/ \
/ \
BaseCategory BaseCategory
(name:Sales) (name:Information)
\
\
MainCategory
(name:Address 3)
\
\
Subcategory
(name:Street Number 2)
import pprint
from xml.etree import ElementTree
with open("sample_xml.xml", 'r') as f:
data = f.read()
xml_data = ElementTree.fromstring(data)
base_categories = xml_data.findall("./BaseCategory")
print("Found %s base_categories." % len(base_categories))
list_dict = []
for base_category in base_categories:
list_dict.append({
"name": base_category.find("Name").text,
"id": int(base_category.find("base_id").text),
"position": int(base_category.find("position").text),
"order_by_type": (True if base_category.find("order_by_type").text.lower() == "true"
else False),
"order_by_asc": (True if base_category.find("order_by_asc").text.lower() == "true"
else False),
})
print("list_dict=%s" % (pprint.pformat(list_dict)))
哪些产出:
Found 2 base_categories.
list_dict=[{'id': 1,
'name': 'Sales',
'order_by_asc': True,
'order_by_type': True,
'position': 10},
{'id': 2,
'name': 'Information',
'order_by_asc': True,
'order_by_type': True,
'position': 20}]
其思想是,BaseCategory
项可以看作是一个自包含的记录(如dict,如果它有助于您查看的话),可以包含(在其中)以下属性:
- 名称位于
name
base\u id
- 数字
位置
- 布尔值
按类型排序
- 布尔值
order\u by\u asc
- 另一个对象
MainCategory
具有自己的字段
因此,每次您将自己定位到这些BaseCategory
节点中的一个节点时,您只需收集它所具有的有趣字段并将它们放入字典中即可
当您这样做时:
base_cats = xml_data.findall('./BaseCategory/Name')
base_cats_id = xml_data.findall('./BaseCategory/base_id')
base_postion = xml_data.findall('./BaseCategory/position')
base_order_by_type = xml_data.findall('./BaseCategory/order_by_type')
base_order_by_asc = xml_data.findall('./BaseCategory/order_by_asc')
您几乎将这些元素(base\u id
,position
…)视为独立的元素,这与XML中的元素不完全相同
但是,如果您绝对确定所有这些列表(base\u cats
,base\u cats\u id
,base\u position
)确实包含相同数量的项目,您仍然可以使用其中一个列表的长度(在下面的len(base\u cats)示例中)重新构建词典
,但它可能是len(base\u cats\u id)
,len(base\u position)
…因为所有这些列表都有相同的长度)在同一步中迭代所有列表:
base_cats = xml_data.findall('./BaseCategory/Name')
base_cats_id = xml_data.findall('./BaseCategory/base_id')
base_postion = xml_data.findall('./BaseCategory/position')
base_order_by_type = xml_data.findall('./BaseCategory/order_by_type')
base_order_by_asc = xml_data.findall('./BaseCategory/order_by_asc')
list_dict = []
for i in range(len(base_cats)):
list_dict.append({
"name": base_cats[i].text,
"id": int(base_cats_id[i].text),
"position": int(base_postion[i].text),
"order_by_type": True if base_order_by_type[i].text.lower() == "true" else False,
"order_by_asc": True if base_order_by_asc[i].text.lower() == "true" else False,
})
print("list_dict=%s" % (pprint.pformat(list_dict)))
XML是什么样子的?对于我收集的信息,您最好遍历BaseCategory
项并获取其子节点?@BorrajaX,我已经在xml中添加了它。很抱歉没有在原来的帖子中添加它。不用担心:)谢谢!谢谢你的帮助。这对我很有帮助,并且能够更好地理解它。最终,我将需要主,子和枚举。虽然有了你的回答,我相信我能使它适应我的需要。谢谢。非常感谢。当您必须这样做时,您只需要看到您的基本类别还包含一个dict(或“object”)maincography
,它有一组“字段”(name
,base\u id
),随后可以包含一个子类别
字段,该字段是一个带有另一组“字段”…等等:-)代码编写得很有趣!再次感谢BorrajaX。我在这个问题上坚持了两天,终于让步了。感谢您的帮助!