【问题标题】:Json to XML with attributes rather than elements带有属性而不是元素的 Json 到 XML
【发布时间】:2021-11-28 20:01:02
【问题描述】:

我需要解析一个像这样的 Json:

{
"operacion": "ingresarOrdenBilateral",
"agente" : "0062",
"comitente" : 7211,
"fechaOrigen" : "2021-09-23T16:51:27.873-03:00",
"tipo" : "V",
"instrumento" : "GD30",
"tipoVenc" : "24",
"precio" : "100000000",
"cantidad" : "1",
"idOrigen" : 10699570
"ejecucion" : "SINCRONICA"
}

到这个 XML:

<ingresarOrdenBilateral 
agente="150" idOrigen="10039" fechaOrigen="2018-08-16T11:28:08.495-03:00" tipo="V" 
instrumento="AA17" tipoVenc="24" cantidad="1000000" precio="1625" formaOp="C" 
ejecucion="SINCRONICA"/> 

我已经尝试了 xmltodict 和 dicttoxml 库,但我无法使用属性而不是元素来获取 XML。另外我认为XML格式不标准。

谢谢!

【问题讨论】:

  • 显示你的代码,并解释你的意思 “我认为 XML 格式不标准”
  • 我已将问题编辑为我认为真正的问题——使用属性与元素;元素然后自动关闭的事实是无关紧要的
  • 请分享您当前的努力(代码)。
  • @Methizul,这些数据存储在哪里?你从文件中读取它吗?或者你从某个服务器检索它?

标签: python json xml parsing xmltodict


【解决方案1】:

首先,使用属性而不是子元素是这种结构的完全标准。它可能比使用子元素少一些,但它并不罕见,当然也不是不标准的。

其次,JSON 和 XML 之间的标准现成转换器永远不会让您有足够的控制权来准确生成您想要的目标结构。如果您想要一种特定的 XML 格式,那么您必须准备对结果进行转换,这通常使用 XSLT 很容易实现。

如果您使用 XSLT 3.0,那么您可以在单个样式表中进行 JSON 到 XML 的转换以及后续的转换;但除此之外,使用您最喜欢的库转换器然后进行 XSLT (1.0+) 转换非常简单。您会发现大量将 XML 元素转换为属性的样式表示例。

【讨论】:

    【解决方案2】:

    如果 XML 这么简单,下面的代码就可以完成这项工作

    data = {
    "operacion": "ingresarOrdenBilateral",
    "agente" : "0062",
    "comitente" : 7211,
    "fechaOrigen" : "2021-09-23T16:51:27.873-03:00",
    "tipo" : "V",
    "instrumento" : "GD30",
    "tipoVenc" : "24",
    "precio" : "100000000",
    "cantidad" : "1",
    "idOrigen" : 10699570,
    "ejecucion" : "SINCRONICA"
    }
    
    xml = '<root>' + ' '.join(f'"{k}"="{v}"' for k,v in data.items()) + '</root>'
    print(xml)
    

    输出

    <?xml version="1.0" encoding="UTF-8"?>
    <root>"operacion"="ingresarOrdenBilateral" "agente"="0062" "comitente"="7211" "fechaOrigen"="2021-09-23T16:51:27.873-03:00" "tipo"="V" "instrumento"="GD30" "tipoVenc"="24" "precio"="100000000" "cantidad"="1" "idOrigen"="10699570" "ejecucion"="SINCRONICA"</root>
    

    【讨论】:

    • 您的代码不会产生您附加的输出。您的代码不会产生附加到问题的输出。您的代码根本不会生成有效的 XML。
    【解决方案3】:

    嗯,使用内置的xml.etree.ElementTree可以在一行内完成:

    import xml.etree.ElementTree as ET
    
    data = {
        "operacion": "ingresarOrdenBilateral",
        "agente": "0062",
        "comitente": 7211,
        "fechaOrigen": "2021-09-23T16:51:27.873-03:00",
        "tipo": "V",
        "instrumento": "GD30",
        "tipoVenc": "24",
        "precio": "100000000",
        "cantidad": "1",
        "idOrigen": 10699570,
        "ejecucion": "SINCRONICA"
    }
    ET.dump(ET.Element(data.pop("operacion"), {k: str(v) for k, v in data.items()}))
    

    输出:

    <ingresarOrdenBilateral agente="0062" comitente="7211" fechaOrigen="2021-09-23T16:51:27.873-03:00" tipo="V" instrumento="GD30" tipoVenc="24" precio="100000000" cantidad="1" idOrigen="10699570" ejecucion="SINCRONICA" />
    

    更新。假设您从文件或服务器加载此 JSON 数据,则可以将 str() 传递给 parse_int 参数 json.load()/json.loads()/requests.Response.json()。它将强制将int 字段解析为str,因此我们可以省略我在上面代码中使用的dict理解:

    import json
    import xml.etree.ElementTree as ET
    
    str_data = '''{
        "operacion": "ingresarOrdenBilateral",
        "agente": "0062",
        "comitente": 7211,
        "fechaOrigen": "2021-09-23T16:51:27.873-03:00",
        "tipo": "V",
        "instrumento": "GD30",
        "tipoVenc": "24",
        "precio": "100000000",
        "cantidad": "1",
        "idOrigen": 10699570,
        "ejecucion": "SINCRONICA"
    }'''
    data = json.loads(str_data, parse_int=str)
    ET.dump(ET.Element(data.pop("operacion"), data))
    

    还有parse_floatparse_constant,您可以以同样的方式使用它们(如果需要,ofc)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-19
      • 2020-04-08
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多