【问题标题】:Generating XML from python dictionary从 python 字典生成 XML
【发布时间】:2014-10-04 21:45:40
【问题描述】:

我有以下结构的python字典:

d={ 'cfdi:Emisor': {'rfc': u'ALF040329CX6', 'nombre': u'ALFATECH, S.A. DE C.V.', 
     'cfdi:RegimenFiscal': {'Regimen': u'Personas morales del r\xe9gimen general'}, 
      'cfdi:ExpedidoEn': {'calle': u'ING. INDUSTRIALES', 'localidad': u'MORELIA', 'pais':   u'M\xe9xico', 'noInterior': 'N/A', 'colonia': u'BUENAVISTA 1A ETAPA', 'noExterior': u'215', 'codigoPostal': u'58228', 'estado': u'Michoac\xe1n', 'municipio': u'MORELIA'}, 
       'cfdi:DomicilioFiscal': {'calle': u'ING. INDUSTRIALES', 'localidad': u'MORELIA', 'pais': u'M\xe9xico', 'noInterior': 'N/A', 'colonia': u'BUENAVISTA 1A ETAPA', 'noExterior': u'215', 'codigoPostal': u'58228', 'estado': u'Michoac\xe1n', 'municipio': u'MORELIA'}, 
        }}

结构由字典内的字典组成。我需要将其转换为 XML,然后我得到以下代码来实现它:

def dict2xml(data_dict, node=False, doc=False):

    parent = False
    if node:
        parent = True

    for element, attribute in data_dict.iteritems():
        if not parent:
            doc = minidom.Document()
        if isinstance(attribute, dict):
            if not parent:
                node = doc.createElement(element)
                dict2xml(attribute, node, doc)
            else:
                child = doc.createElement(element)
                dict2xml(attribute, child, doc)
                node.appendChild(child)
        elif isinstance(attribute, list):
            child = doc.createElement(element)
            for attr in attribute:
                if isinstance(attr, dict):
                    dict2xml(attr, child, doc)
            node.appendChild(child)
        else:
            if isinstance(attribute, str) or isinstance(attribute, unicode):
                attribute = str(attribute)
            else:
                    attribute = str(attribute)
            node.setAttribute(element, attribute)
            # print "attribute",unicode( attribute, 'UTF-8')
    if not parent:
        doc.appendChild(node)
    print doc.toprettyxml(indent="     ", encoding='utf-8')
    return doc

这个函数在之前的字典中工作得很好,并返回这个:

<cfdi:Emisor nombre="ALFATECH, S.A. DE C.V." rfc="ALF040329CX6">
    <cfdi:RegimenFiscal Regimen="Personas morales del régimen general"/>
    <cfdi:ExpedidoEn calle="ING. INDUSTRIALES" codigoPostal="58228" colonia="BUENAVISTA 1A ETAPA" estado="Michoacán" localidad="MORELIA" municipio="MORELIA" noExterior="215" noInterior="N/A" pais="México"/>
    <cfdi:DomicilioFiscal calle="ING. INDUSTRIALES" codigoPostal="58228" colonia="BUENAVISTA 1A ETAPA" estado="Michoacán" localidad="MORELIA" municipio="MORELIA" noExterior="215" noInterior="N/A" pais="México"/>
</cfdi:Emisor>

这是我一直在等待的,但现在我需要对这个结构基本相同但包含不同元素的字典做同样的事情:

d3={ 'catalogocuentas:Catalogo': {'rfc': u'ALF040329CX6', 'xmlns:catalogocuentas':'"http://www.sat.gob.mx/catalogocuentas"', 'xmlns:xsi':'"http://www.w3.org/2001/XMLSchema-instance"', 'xsi:schemaLocation':'"http://www.sat.gob.mx//catalogocuentas"', 'Ano':'2014', 'Mes':'02', 'TotalCtas':'219','version':'1.0', 
     'catalogocuentas:Ctas': {'Natur': u'D', 'nivel':'2', 'SubCtaDe':'1110-000-000', 'Desc':'CAJA CHICA', 'NumCta':'1110-001-000', 'CodAgrup':'1.1'}, 
      'catalogocuentas:Ctas': {'Natur': u'D', 'nivel':'3', 'SubCtaDe':'1120-001-000', 'Desc':'Banamex 741107-1', 'NumCta':'1120-001-001', 'CodAgrup':'2.1'}, 
       'catalogocuentas:Ctas': {'Natur': u'D', 'nivel':'3', 'SubCtaDe':'1120-001-000', 'Desc':'Bancomer 12911256971', 'NumCta':'1120-001-002', 'CodAgrup':'2.1'} 
        }}

你们可以看到主要的区别是这本字典对内部元素(字典)有相同的标签,我得到了以下结果:

<?xml version="1.0" encoding="utf-8"?>
   <catalogocuentas:Catalogo Ano="2014" Mes="02" TotalCtas="219" rfc="ALF040329CX6"     version="1.0" xmlns:catalogocuentas="&quot;http://www.sat.gob.mx/catalogocuentas&quot;" xmlns:xsi="&quot;http://www.w3.org/2001/XMLSchema-instance&quot;" xsi:schemaLocation="&quot;http://www.sat.gob.mx//catalogocuentas&quot;">
         <catalogocuentas:Ctas CodAgrup="2.1" Desc="Bancomer 12911256971" Natur="D" NumCta="1120-001-002" SubCtaDe="1120-001-000" nivel="3"/>
   </catalogocuentas:Catalogo>

如您所见,我只从 d3 获得了最后一个元素(字典),而不是全部。

由此我可以得出结论,问题可能是在这本字典中我的所有元素都有相同的标签。

这是真正的问题吗?

任何建议将不胜感激!!!

提前致谢。

【问题讨论】:

    标签: python xml dictionary xml-parsing minidom


    【解决方案1】:

    为此已经存在一些库,one of which I created。使用 xmler 包,您可以轻松地将字典转换为以下 xml:

    <?xml version="1.0" encoding="UTF-8"?><?xml version="1.0" ?>
    <cfdi:Emisor xmlns:cfdi="www.sat.gob.mx/cfd/3">
        <cfdi:DomicilioFiscal>
            <pais>Mexico</pais>
            <localidad>MORELIA</localidad>
            <estado>Michoacán</estado>
            <noExterior>215</noExterior>
            <municipio>MORELIA</municipio>
            <calle>ING. INDUSTRIALES</calle>
            <noInterior>N/A</noInterior>
            <codigoPostal>58228</codigoPostal>
            <colonia>BUENAVISTA 1A ETAPA</colonia>
        </cfdi:DomicilioFiscal>
        <nombre>ALFATECH, S.A. DE C.V.</nombre>
        <cfdi:ExpedidoEn>
            <pais>Mexico</pais>
            <localidad>MORELIA</localidad>
            <estado>Michoacán</estado>
            <noExterior>215</noExterior>
            <municipio>MORELIA</municipio>
            <calle>ING. INDUSTRIALES</calle>
            <noInterior>N/A</noInterior>
            <codigoPostal>58228</codigoPostal>
            <colonia>BUENAVISTA 1A ETAPA</colonia>
        </cfdi:ExpedidoEn>
        <rfc>ALF040329CX6</rfc>
        <cfdi:RegimenFiscal>
            <Regimen>Personas morales del régimen general</Regimen>
        </cfdi:RegimenFiscal>
    </cfdi:Emisor>
    

    要获得该 XML 结构并使其正确打印,您必须稍微修改您的字典,因为您目前没有为 cfdi 定义 xml 命名空间。我使用了以下字典:

    d = {
        "cfdi:Emisor": {
            "@attrs": {
                "xmlns:cfdi": "www.sat.gob.mx/cfd/3"
            },
            "rfc": "ALF040329CX6",
            "nombre": "ALFATECH, S.A. DE C.V.",
            "cfdi:RegimenFiscal": {
                "Regimen": "Personas morales del r\xe9gimen general"
            },
            "cfdi:ExpedidoEn": {
                "calle": "ING. INDUSTRIALES",
                "localidad": "MORELIA",
                "pais": "Mexico",
                "noInterior": "N/A",
                "colonia": "BUENAVISTA 1A ETAPA",
                "noExterior": "215",
                "codigoPostal": "58228",
                "estado": "Michoac\xe1n",
                "municipio": "MORELIA"
            },
            "cfdi:DomicilioFiscal": {
                "calle": "ING. INDUSTRIALES",
                "localidad": "MORELIA",
                "pais": "Mexico",
                "noInterior": "N/A",
                "colonia": "BUENAVISTA 1A ETAPA",
                "noExterior": "215",
                "codigoPostal": "58228",
                "estado": "Michoac\xe1n",
                "municipio": "MORELIA"
            }
        }
    }
    

    然后跑了

    print(xmler(d, customRoot=None, pretty=True))
    

    注意字典中的@attrs 键。它将属性添加到元素。您还可以在此处使用@ns 键来设置命名空间,而不是使用冒号分隔的字符串。

    【讨论】:

      【解决方案2】:

      你的代码格式让我眼睛疼。 Python formatting style guide 是你的朋友。特别是您滥用了最大行长。

      如果您想将 python 字典格式化为 XML,有许多标准选项。看到这个previous question for some solutions.

      Python 字典只允许基于相同键的单个元素,重复的条目会覆盖以前的条目。

      【讨论】:

      • 谢谢,所以......如果python覆盖以前的条目......使用minidom绝对不可能做到这一点??
      • 您不能构造具有重复键的 Python 字典。这不是 DOM 或 XML 的问题。你不是在构建你认为你在哪里的字典。您可以构造一个 Python dict,其中单个键值是对象列表并将其序列化为 XML。
      猜你喜欢
      • 1970-01-01
      • 2014-05-17
      • 2013-02-06
      • 2020-01-28
      • 2019-05-09
      • 1970-01-01
      • 1970-01-01
      • 2021-01-23
      • 2020-01-18
      相关资源
      最近更新 更多