JSON到XML的转换

时间:2013-12-30 23:01:39

标签: xml json mapping

将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!

2 个答案:

答案 0 :(得分:6)

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

  • 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>

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

  • 名称
  • 喜欢
  • 如下:用于将一个RDF实体链接到另一个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用语中的“元组”)所代表的清晰声明。我认为这表明它是关于信息而不是数据格式!

为了完整起见,RDF信息以JSON-LD格式显示:

{
  "@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,其与其他数据实体的关系可以直观地绘制:

enter image description here

RDF刚刚开始

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

我并不声称自己是数据处理方面的专家。我所承认的是,一些非常聪明的人一直在关注这个问题。这些概念很难学习,但为了更好地理解信息理论是值得的。

答案 1 :(得分:0)

您需要使用这两种工具json_decode()PEAR::XML_Serializer

的一些变体