【问题标题】:Parsing Solr XML into Python Dictionary将 Solr XML 解析为 Python 字典
【发布时间】:2011-03-28 10:45:54
【问题描述】:

我是 python 新手,正在尝试将 xml 文档(填充了 solr 实例的文档)传递到 python 字典中。我很难真正做到这一点。我曾尝试使用 ElementTree 和 minidom,但似乎无法获得正确的结果。

这是我的 XML 结构:

<add>
    <doc>
        <field name="genLatitude">45.639968</field>
        <field name="carOfficeHoursEnd">2000-01-01T09:00:00.000Z</field>
        <field name="genLongitude">5.879745</field>
    </doc>
    <doc>
        <field name="genLatitude">46.639968</field>
        <field name="carOfficeHoursEnd">2000-01-01T09:00:00.000Z</field>
        <field name="genLongitude">6.879745</field>
    </doc>
</add>

从这里我需要把它变成一个字典,看起来像:

doc {
    "genLatitude": '45.639968',
    "carOfficeHoursEnd": '2000-01-01T09:00:00.000Z',
    "genLongitude": '5.879745',
    }

我不太熟悉字典的工作原理,但还有一种方法可以将所有“文档”放入一个字典中。

干杯。

【问题讨论】:

    标签: python xml xml-deserialization elementtree minidom


    【解决方案1】:
    import xml.etree.cElementTree as etree
    from pprint import pprint
    
    root = etree.fromstring(xmlstr) # or etree.parse(filename_or_file).getroot()
    
    docs = [{f.attrib['name']: f.text for f in doc.iterfind('field[@name]')}
            for doc in root.iterfind('doc')]
    pprint(docs)
    

    输出

    [{'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z',
      'genLatitude': '45.639968',
      'genLongitude': '5.879745'},
     {'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z',
      'genLatitude': '46.639968',
      'genLongitude': '6.879745'}]
    

    xmlstr 在哪里:

    xmlstr = """
    <add>
        <doc>
            <field name="genLatitude">45.639968</field>
            <field name="carOfficeHoursEnd">2000-01-01T09:00:00.000Z</field>
            <field name="genLongitude">5.879745</field>
        </doc>
        <doc>
            <field name="genLatitude">46.639968</field>
            <field name="carOfficeHoursEnd">2000-01-01T09:00:00.000Z</field>
            <field name="genLongitude">6.879745</field>
        </doc>
    </add>
    """
    

    【讨论】:

    • 很好地使用了cElementTreepprint,以及字典理解。请注意,仅从 2.7 开始支持该语法。
    • @Giulio Piancastelli: dict 理解可以在 Python dict((f.attrib['name'], f.text) for f in doc.iterfind('field[@name]'))
    【解决方案2】:

    如果您将wt=python 添加到请求参数,Solr 可以返回 Python 字典。要将此文本响应转换为 Python 对象,请使用 ast.literal_eval(text_response)

    这比解析 XML 要简单得多。

    【讨论】:

      【解决方案3】:

      使用 ElementTree 的可能解决方案,输出格式非常漂亮,例如:

      >>> import xml.etree.ElementTree as etree
      >>> root = etree.parse(document).getroot()
      >>> docs = []
      >>> for doc in root.findall('doc'):
      ...   fields = {}
      ...   for field in doc:
      ...     fields[field.attrib['name']] = field.text
      ...   docs.append(fields)
      ... 
      >>> print docs
      [{'genLongitude': '5.879745',
        'genLatitude': '45.639968',
        'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z'},
       {'genLongitude': '6.879745',
        'genLatitude': '46.639968',
        'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z'}]
      

      您展示的 XML 文档没有提供一种方法来区分每个 doc,因此我认为列表是收集每个字典的最佳结构。

      确实,如果你想将每个doc 数据插入到另一个字典中,当然可以,但是你需要为那个字典选择一个合适的键。例如,使用 Python 为每个对象提供的id,您可以这样写:

      >>> docs = {}
      >>> for doc in root.findall('doc'):
      ...   fields = {}
      ...   for field in doc:
      ...     fields[field.attrib['name']] = field.text
      ...   docs[id(fields)] = fields
      ... 
      >>> print docs
      {3076930796L: {'genLongitude': '6.879745',
                     'genLatitude': '46.639968',
                     'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z'},
       3076905540L: {'genLongitude': '5.879745',
                     'genLatitude': '45.639968',
                     'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z'}}
      

      本示例旨在让您了解如何使用外部字典。如果你决定走这条路,我建议你找到一个有意义且可用的密钥,而不是 id 返回的对象的内存地址,它可以在运行之间改变。

      【讨论】:

      【解决方案4】:

      将来自外部的任何字符串直接评估为 python 是有风险的。谁知道里面有什么。

      我建议使用 json 接口。比如:

      import json
      import urllib2
      
      response_dict = json.loads(urllib2.urlopen('http://localhost:8080/solr/combined/select?wt=json&q=*&rows=1').read())
      
      #to view the dict
      print json.dumps(answer, indent=1)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多