【问题标题】:Python Parse XML to JSONPython 将 XML 解析为 JSON
【发布时间】:2015-05-25 23:32:50
【问题描述】:

我目前正在处理一些有趣的 XML 字符串响应。本质上,我收到的 XML 是嵌套的,但它读起来像 CSV 文件。示例:

xml = <?xml version="1.0" encoding="ISO-8859-1"?>
<ThisDocument protocol="OCI" xmlns="C" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<sessionId xmlns="">29348u29!!4nthisSucks!==</sessionId>
  <command echo="" xsi:type="GroupGetListInServiceProviderResponse" xmlns="">
    <groupTable>
      <colHeading>Group Id</colHeading>
      <colHeading>Group Name</colHeading>
      <colHeading>User Limit</colHeading>
      <row>
        <col>LRB7905</col>
        <col>Test1</col>
        <col>25</col>
      </row>
      <row>
        <col>LRB9294</col>
        <col>Test2</col>
        <col>100</col>
      </row>
      <row>
        <col>LRB8270</col>
        <col>Test3</col>
        <col>10</col>
      </row>
      <row>
        <col>LRB8212</col>
        <col>Test4</col>
        <col>25</col>
      </row>
      <row>
        <col>LRB8175</col>
        <col>Test5</col>
        <col>25</col>
      </row>
    </groupTable>
  </command>
</ThisDocument>

在我从相关服务器收到的响应中,“colHeading”是“key”,每个“row”的“col”对应于该值。这似乎是一个易于映射的结构,但我想不出一种“PYTHONIC”方式来执行这项任务。期望的结果是:

{
  "groupTable": [
    {
        "Group ID": "LRB7905",
        "Group Name": "Test1",
        "User Limit": "25"
    },
    {
        "Group ID": "LRB9294",
        "Group Name": "Test2",
        "User Limit": "100"
    },
    {
        "Group ID": "LRB8270",
        "Group Name": "Test3",
        "User Limit": "10"
    },
    {
        "Group ID": "LRB8212",
        "Group Name": "Test4",
        "User Limit": "25"
    },
    {
        "Group ID": "LRB8175",
        "Group Name": "Test5",
        "User Limit": "25"
    }
  ]
}

我真正需要的信息包含在 XML 的“col”字段中,colHeadings 的数量对应于每个“行”中的值的数量。到目前为止,我已经能够将值操作到 CSV 文件中,但最终,我需要使用键值对创建 JSON 对象(dicts)。我使用了不同的库/模块等......但我想出的最佳方法是将 colHeadings 和 Values 分成两个列表,然后将它们组合起来。

到目前为止的代码:

xmlroot = ET.fromstring(xml)

headings =[]
values = []

def breakoutLists(xmlroot):
    for columnHeading in root.iter('colHeading'):
        headings.append(columnHeading.text)
    for column in root.iter('col'):
        values.append(column.text)
    return headings, values

breakoutLists(xmlroot)

zipped = dict(itertools.izip(values, itertools.cycle(headings)))
print zipped

这会产生一个字典,但顺序是values: keys 而不是keys: values

如果有任何关于完成这项任务的最佳方式的建议,我将不胜感激。 提前谢谢!!!

编辑在 Eric 的帮助下,我得以实现我的目标!

groupResp = {'groupResponse': []}    
def breakoutLists(root):
    headings = [h.text for h in root.iter('colHeading')]

    return (
        {
            h: col.text
            for h, col in zip(headings, row.iter('col'))
        }
        for row in root.iter('row')
    )

data = list(breakoutLists(root))

for item in data:
    groupResp['groupResponse'].append(item)

print json.dumps(groupResp)

我可能可以稍微清理一下以在初始函数期间附加字典,但我现在很好!

【问题讨论】:

  • zipped = dict(itertools.izip(itertools.cycle(headings), values )) 而不是 zipped = dict(itertools.izip(values, itertools.cycle(headings))) ?关于 .izip() : #product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
  • @SerCrAsH:这是我的第一个想法,但由于cycle 而不起作用 - 请注意,这构建了一个dict,但他想要一个list&lt;dict&gt;

标签: python json xml


【解决方案1】:

您的代码使数据变平,这是无用的 - 您需要遍历行对象

def breakoutLists(xmlroot):
    headings = [h.text for h in root.iter('colHeading')]

    return (
        {
            h: col.text
            for h, col in zip(headings, row.iter('column'))
        }
        for row in root.iter('row')
    )

data = list(breakoutLists(html))

【讨论】:

  • 非常感谢!这对我有很大帮助......我之前使用 for 循环有点接近,但因为我无法正确操作数据而放弃了它。在您的帮助和几行代码的帮助下,我能够实现我的目标:
猜你喜欢
  • 2011-10-08
  • 1970-01-01
  • 2023-03-24
  • 2021-10-31
  • 2022-01-04
  • 2019-05-05
  • 2018-11-17
  • 2015-06-30
  • 1970-01-01
相关资源
最近更新 更多