【问题标题】:JSON to XML conversionJSON 到 XML 的转换
【发布时间】:2014-01-17 21:34:51
【问题描述】:

将 JSON 转换为 XML 并返回的最佳方法是什么。例如下面的 JSON

{
    "user": "gerry",
    "likes": [1, 2, 4],
    "followers": [
        {
            "name": "megan"
        },
        {
            "name": "pupkin"
        }
    ]
}

可以像这样转换成 XML (#1):

<?xml version="1.0" encoding="UTF-8" ?>
<user>gerry</user>
<likes>1</likes>
<likes>2</likes>
<likes>4</likes>
<followers>
    <name>megan</name>
</followers>
<followers>
    <name>pupkin</name>
</followers>

或像这样(#2):

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <likes>
      <element>1</element>
      <element>2</element>
      <element>4</element>
   </likes>
   <followers>
      <element>
         <name>megan</name>
      </element>
      <element>
         <name>pupkin</name>
      </element>
   </followers>
   <user>gerry</user>
</root>

特别是,不同之处在于转换数组。对象属性转换非常简单。我也确信还有其他方法可以将 JSON 转换为 XML。

所以问题是:最好的方法是什么?有什么标准吗?

另一个问题:有没有办法以某种数学形式表达转换映射本身。例如,是否有可能描述一个映射,使得当给定 JSON 对象和映射对象时转换函数将准确地知道要生成哪个 XML。反过来也一样。

XML_1 = convert(JSON, mapping_1)
XML_2 = convert(JSON, mapping_2)
JSON  = convert(XML_1, mapping_1)
JSON  = convert(XML_2, mapping_2)
JSON  = convert(XML_1, mapping_2) # Error!

【问题讨论】:

    标签: xml json mapping


    【解决方案1】:

    您显然对数据序列化背后的理论感兴趣。我将尝试使用以下标题进行解释。

    • XML 作为数据序列化格式的问题
    • 为什么偏爱其他格式
    • 这真的是关于信息和关系

    我要介绍的是Semantic web 以及它如何以各种不同格式格式化数据。


    XML 作为数据序列化格式的问题

    正如您所发现的,有多种方法可以在 XML 中构造数据。这是因为 XML 从文档标记开始。 XML 没有内置的方式来描述简单的数据结构,如列表或散列。

    不是自我描述

    这是一个简单的例子:

    <data>
      <user name="gerry"/>
    </data>
    

    这可以反序列化为一个简单的哈希:

    data.user.name = "gerry"
    

    或者不那么明显的哈希列表:

    data.user[0].name = "gerry"
    

    事实上,一个不同的 XML 文档可以指定多个用户标签:

    <data>
      <user name="gerry"/>
      <user name="tom"/>
    </data>
    

    救援的 XML 架构

    解决这个问题的方法是设计一个单独的模式规范来描述文档的格式:

    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="data">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="user" maxOccurs="unbounded" minOccurs="0">
              <xs:complexType>
                <xs:simpleContent>
                  <xs:extension base="xs:string">
                    <xs:attribute type="xs:string" name="name" use="optional"/>
                  </xs:extension>
                </xs:simpleContent>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    person 标签被描述为一个元素序列...所以这使得 XML 解析器能够将此信息存储在一个列表结构中。

    这是许多处理 XML 数据的 Web 服务框架所采用的方法。消息格式在 WSDL/XML 模式中描述,处理消息的编程代码是自动生成的。


    为什么偏爱其他格式

    JSONYAML 等格式专门用于序列化数据。 它们不需要架构文档来明确解析数据。

    但是……即便如此……JSON 和 YAML 并不能解决所有问题。虽然数据乍一看更明显,但没有描述数据结构的标准......

    之前我曾批评过 XML 模式,但这些模式对于确定一段数据是否可以通过编程方式使用(有效)非常有用。即便如此,XML Schema 也不能告诉我一段数据与另一段数据之间的关系。


    这真的是关于信息和关系

    Semantic web 运动试图创建一个自我描述和协作的互联网。问题是(恕我直言)相关标准很复杂,难以理解和应用。开始的地方是RDF:

    它被设计为一种通用信息交换格式,并且以独立于数据实际序列化方式的方式巧妙地工作。

    示例

    您的简单示例并表示为 RDF XML:

    <?xml version="1.0"?>
    <rdf:RDF xmlns:user="http://myspotontheweb.com/user/1.0/" xmlns:ex="http://myspotontheweb.com/example/user/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:Description rdf:about="http://myspotontheweb.com/example/user/1">
            <user:name>gerry</user:name>
            <user:likes>1</user:likes>
            <user:likes>2</user:likes>
            <user:likes>4</user:likes>
        </rdf:Description>
        <rdf:Description rdf:about="http://myspotontheweb.com/example/user/2">
            <user:name>tom</user:name>
            <user:likes>2</user:likes>
            <user:likes>4</user:likes>
            <user:likes>6</user:likes>
            <user:follows rdf:resource="http://myspotontheweb.com/example/user/1" />
        </rdf:Description>
        <rdf:Description rdf:about="http://myspotontheweb.com/example/user/3">
            <user:name>felix</user:name>
            <user:likes>3</user:likes>
            <user:likes>5</user:likes>
            <user:follows rdf:resource="http://myspotontheweb.com/example/user/1" />
        </rdf:Description>
    </rdf:RDF>
    

    每个数据项都有一个唯一标识符和一组自定义属性:

    • 姓名
    • 喜欢
    • follows : 用于将一个 RDF 实体链接到另一个。

    XML 只是表示 RDF 的一种方式,我更喜欢更紧凑的N3 RDF format

    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix user: <http://myspotontheweb.com/user/1.0/> .
    @prefix ex: <http://myspotontheweb.com/example/user/> .
    
    ex:1 user:name "gerry" .
    ex:1 user:likes "1" .
    ex:1 user:likes "2" .
    ex:1 user:likes "4" .
    
    ex:2 user:name "tom" .
    ex:2 user:likes "2" .
    ex:2 user:likes "4" .
    ex:2 user:likes "6" .
    ex:2 user:follows ex:1 .
    
    ex:3 user:name "felix" .
    ex:3 user:likes "3" .
    ex:3 user:likes "5" .
    ex:3 user:follows ex:1 .
    

    再次注意顶部的自定义前缀声明以及每条数据(RDF 用语中的“元组”)代表什么的清晰声明。我认为这表明它是关于信息而不是数据格式!

    为了完整起见,以JSON-LD 格式呈现的RDF 信息:

    {
      "@graph": [
        {
          "@id": "http://myspotontheweb.com/example/user/3",
          "http://myspotontheweb.com/user/1.0/follows": {
            "@id": "http://myspotontheweb.com/example/user/1"
          },
          "http://myspotontheweb.com/user/1.0/likes": [
            "3",
            "5"
          ],
          "http://myspotontheweb.com/user/1.0/name": "felix"
        },
        {
          "@id": "http://myspotontheweb.com/example/user/2",
          "http://myspotontheweb.com/user/1.0/follows": {
            "@id": "http://myspotontheweb.com/example/user/1"
          },
          "http://myspotontheweb.com/user/1.0/likes": [
            "2",
            "6",
            "4"
          ],
          "http://myspotontheweb.com/user/1.0/name": "tom"
        },
        {
          "@id": "http://myspotontheweb.com/example/user/1",
          "http://myspotontheweb.com/user/1.0/likes": [
            "2",
            "4",
            "1"
          ],
          "http://myspotontheweb.com/user/1.0/name": "gerry"
        }
      ]
    }
    

    注意事项:

    • 有多种方法可以将 RDF 表示为 JSON 参见 JSON+RDF

    示例图

    一旦将信息表示为 RDF,它与其他数据实体的关系就可以直观地绘制出来:

    RDF 只是开始

    语义网走得更远,它只从 RDF 开始。有一些类似于 XML 模式的标准用于发布元组之间易于理解的关系。使用这些可以开始以非常有趣的方式操作 RDF 数据。

    我并不声称自己是数据处理方面的专家。我承认的是,一些非常聪明的人已经研究这个问题已经有一段时间了。这些概念很难学习,但为了更好地理解信息论是值得的。

    【讨论】:

      【解决方案2】:

      您需要使用json_decode()PEAR::XML_Serializer 这两个工具的一些变体

      【讨论】:

      • 谢谢,但我更感兴趣的是理论而不是具体的工具。
      猜你喜欢
      • 1970-01-01
      • 2012-08-16
      • 2021-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      • 2014-03-27
      相关资源
      最近更新 更多