与具有属性的XML对应的JSON ?

时间:2020-11-27 22:18:03

I am designing an API for my webapp.

我正在为我的webapp设计一个API。

I was thinking to support only JSON responses (not XML) because more streamlined.

我想只支持JSON响应(而不是XML),因为它更加流线型。

But I have just bumped to this XML:

但是我刚刚碰到了这个XML:

<folders>
    <folder id="123" private="0" archived="0" order="1">Shopping</folder>
</folders>

and I was wondering how the corresponding JSON would be. I have the feeling, in this case, XML would be more compact.

我想知道对应的JSON是什么。我有这种感觉,在这种情况下,XML会更加紧凑。

Thanks, Dan

谢谢你,丹

12 个解决方案

#1


15  

Perhaps:

可能:

{
  "folders": [
    { "id":123, "private":0, "archived":0, "order":1, "title":"Shopping" },
    ...
  ]
}

Because there is not an exact correspondence between XML and JSON, you are free (e.g. have to define) how the two data-structures map. For instance, in the above, the "folder" element is implicit in the nested objects in the "folders" array.

因为XML和JSON之间没有确切的对应关系,所以您可以*地(例如必须定义)如何映射这两个数据结构。例如,在上面,“文件夹”元素隐含在“文件夹”数组中的嵌套对象中。

This could be expanded as in:

这可以扩大如下:

"folders": [{"folder": { .... }]

Etc, but there is still the problem of not being able to capture content+attributes as consistently as XML. In any case, your data-structure -> JSON|XML serializer likely works in a particular way (and please, please, use a library, not "hand-rolled" JSON-string-munging). That is; the format of the XML and JSON should be uniformly dictated (somehow) by the data-structure for transmission.

但是仍然存在不能像XML那样一致地捕获内容+属性的问题。无论如何,您的数据结构——> JSON|XML序列化器可能以特定的方式工作(请使用一个库,而不是“手工”JSON-string-munging)。这是;XML和JSON的格式应该由数据结构统一地(以某种方式)进行传输。

#2


11  

You need something like this:

你需要这样的东西:

{
    "folders": {
        "folder":{ 
        "@": {
            "id": "123",
            "private": "0",
            "archived": "0",
            "order": "1"
            },
        "#": "Shopping"
        }
    }
}

At least this works correctly with js2xmlparser.

至少,这在js2xmlparser中是正确的。

#3


7  

An example of how YQL presents XML and the corresponding JSON. No need to know anything about YQL to understand this but if you are interested your can check the YQL console and try it out yourself in the YQL console

YQL如何表示XML和相应的JSON的示例。不需要了解任何有关YQL的知识就可以理解这一点,但是如果您感兴趣,可以检查YQL控制台并在YQL控制台自己尝试它

XML

XML

<results>
    <a href="/">NBA</a>
    <a class="topnav" href="#">TEAMS</a>
    <a href="/teams/">Teams</a>
    <a href="/hawks/">Atlanta</a>

JSON

JSON

"results": {
  "a": [
    {
     "href": "/",
     "content": "NBA"
    },
    {
     "class": "topnav",
     "href": "#",
     "content": "TEAMS"
    },
    {
     "href": "/teams/",
     "content": "Teams"
    },
    {
     "href": "/hawks/",
     "content": "Atlanta"
    },

#4


7  

There is a JSON notation / convention called badgerfish attempts to standardizes (at least its own terms) the way of preserving of most of the low level XML semantics when XML DOM represented as JSON DOM (with attributes of course) (see http://badgerfish.ning.com/).

有一种叫做badgerfish的JSON表示法/约定试图标准化(至少是它自己的术语),当XML DOM表示为JSON DOM(当然包含属性)时,保持大部分低级别XML语义的方法(参见http://badgerfish.ning.com/)。

So you can easily convert back the badgerfishied-json representation to the XML representation and you still work on the structure with your favorite XML toolset (for me its XPATH / QUERY expressions and tools).

因此,您可以轻松地将badgerfi -json表示转换回XML表示,并且仍然使用您最喜欢的XML工具集(对我来说是它的XPATH /查询表达式和工具)处理结构。

It has also easy to memorize syntax rules (total 9) like: "Attributes go in properties whose names begin with @". You can work on badgerfishied-json in the text editor without overloading your neural circuitry unnecessarily. Usually you can memorize them in the first pass.

它还很容易记住语法规则(总共9条),比如:“属性位于名称以@开头的属性中”。您可以在文本编辑器中使用badgerfishie -json,而无需不必要地重载您的神经电路。通常你可以一开始就记住它们。

#5


4  

Could be compact in the JSON too, attribute is just the same as the value inside tag

在JSON中也可以是紧凑的,属性和标签中的值一样吗

from here:

从这里开始:

http://www.json.org/example.html

http://www.json.org/example.html

{"widget": {
    "debug": "on",
    "window": {
        "title": "Sample Konfabulator Widget",
        "name": "main_window",
        "width": 500,
        "height": 500
    },
    "image": { 
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 250,
        "alignment": "center"
    }
}}  

The same text expressed as XML:

用XML表示的同一文本:

<widget>
    <debug>on</debug>
    <window title="Sample Konfabulator Widget">
        <name>main_window</name>
        <width>500</width>
        <height>500</height>
    </window>
    <image src="Images/Sun.png" name="sun1">
        <hOffset>250</hOffset>
        <vOffset>250</vOffset>
        <alignment>center</alignment>
    </image>
</widget>

#6


4  

It seems to me that the most exact correspondence between XML and JSON would need to represent an XML node as a triplet (i.e. array): [name, attributes, value], with name being a string, attributes an object with attribute names as keys and attribute values as (string) values, and value a string (for atomic values) or an array of such triplets.

在我看来,最准确的对应的XML和JSON需要代表XML节点三联体(即数组):名称、属性值,名字是一个字符串,一个对象属性与属性名称作为键和属性值(字符串)值,和价值一个字符串(对于原子值)或一个数组的三胞胎。

By such mapping the JSON-equivalent of

通过这样的映射,json等价于

<folders>
    <folder id="123" private="0" archived="0" order="1">Shopping</folder>
</folders>

would be

[  "folders",
   {}, 
   [
      [  "folder", 
         {   "id": "123",
             "private": "0",
             "archived": "0",
             "order": "1"
         },
         "Shopping"
      ]
   ]
]

Actually the idea behind this mapping is that:

实际上,这个映射背后的想法是:

1) XML-JSON transformation be reversible. 2) The "sibling" relationship of sub-nodes be preserved

1) XML-JSON转换是可逆的。2)保留子节点的“兄弟”关系

At the same time the distinction between attribute nodes and value nodes is explicit here.

与此同时,属性节点和值节点之间的区别是显而易见的。

Does it make sense? And does it justify the complexity overhead?

它有意义吗?它是否证明复杂性开销是合理的?

#7


0  

JSON is more uniform than XML and doesn't distinguish between plain-text attributes and hierarchical contents. The natural representation for your example would be

JSON比XML更统一,不区分纯文本属性和分层内容。您的示例的自然表示形式是

[
  {"id": 123, "private": 0, "archived": 0, "order": 1, "name": "Shopping"}
]

This is still more compact than the respective XML.

这仍然比各自的XML更紧凑。

#8


0  

"content" is used for the actual text, while the attributes are its siblings in the resulted JSON:

“content”用于实际的文本,而属性是其结果JSON中的兄弟属性:

{ "folders":
 { "folder":
  {
   "archived":0,
   "private":0,
   "id":123,
   "content":"Shopping",
   "order":1
  }
 }
}

Java implementation details

Java实现细节

#9


0  

I've ran into a scenario that needs both XML and JSON for input and output based on what was being passed in. I found a way that works with XML Attributes/Properties and JSON. Now note, it's how it coded in Java, makes it work this way.

我遇到了一个场景,根据传入的内容,输入和输出都需要XML和JSON。我找到了一种处理XML属性/属性和JSON的方法。注意,它是用Java编写的,它是这样工作的。

My XML Example:

我的XML示例:

<Log>
    <datetime>05/05/2017 13:45:22</datetime>
    <sessionid>2da236d2-3852-4a09-8067-198193d2828b</sessionid>
    <message msgType="Debug">This is my message</message>
</Log>

My JSON Example:

我的JSON的例子:

{
    "datetime":"05/05/2017 13:45:22",
    "sessionid":"2da236d2-3852-4a09-8067-198193d2828b",
    "message": {
        "content":"This is a testa",
        "msgType":"Debug"
    }
}

How I made it work via code Log.java:

我是如何通过代码日志来工作的。

package log;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

@JacksonXmlRootElement(localName = "Log")
public class Log {
    @JacksonXmlProperty(localName = "datetime")
    private String datetime;
    @JacksonXmlProperty(localName = "sessionid")
    private String sessionid;
    @JacksonXmlProperty(localName = "message")
    private Message message;

    public Log() {
        this.sessionid = "0";
        this.datetime = "";
        this.message = new Message();
    }

    public String getDatetime() {
        return datetime;
    }

    public void setDatetime(String datetime) {
        this.datetime = datetime;
    }

    public String getSessionid() {
        return sessionid;
    }

    public void setSessionid(String sessionid) {
        this.sessionid = sessionid;
    }

    public Message getMessage() {
        return message;
    }

    public void setMessage(Message message) {
        this.message = message;
    }
}

Message.java, Note the @JacksonXmlText below, which is key:

消息。请注意下面的@JacksonXmlText,这是关键:

package log;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;

public class Message {
    @JacksonXmlProperty(localName = "msgType", isAttribute = true)
    private String msgType;
    @JacksonXmlText
    private String content;

    public Message() {
        this.content = "";
    }

    public String getMsgType() {
        return msgType;
    }

    public void setMsgType(String msgType) {
        switch(msgType.toLowerCase())
        {
        case "test":
        case "debug":
        case "warn":
        case "error":
            break;
        default:
            msgType = "Unknown";
            break;
        }

        this.msgType = msgType;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

Caller within LogController.java:

调用者在LogController.java:

..
@RequestMapping(value = "/Logger", produces={"application/xml", "application/json"}, consumes={"application/xml", "application/json"})
public ResponseEntity<String> Logger(@RequestBody String logInfo, @RequestHeader("Content-Type") String contentType) {
    try 
    {
        String xml = "";
        Log logObj = null; 
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.add("Content-Type", contentType);

        if (contentType.toLowerCase().contains("json"))
        {
           ObjectMapper mapper = new ObjectMapper();
           logObj = mapper.readValue(logInfo, Log.class);
           xml = mapper.writeValueAsString(logObj);
        }
        else if (contentType.toLowerCase().contains("xml"))
        {
           XmlMapper xmlMapper = new XmlMapper();
           logObj = xmlMapper.readValue(logInfo, Log.class);
           xml = xmlMapper.writeValueAsString(logObj);
        }
        else
           return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);

        //TODO GWL
        //Save Log data, via Async Web Service, Data, or System 
        return new ResponseEntity<String>(xml, responseHeaders, HttpStatus.OK);
    } 
    catch( Exception ex)
    {
        ex.printStackTrace();
        return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
    }
}

#10


0  

If you like to have an overview of the various conventions for XML to JSON conversion, there is a nice overview at: http://wiki.open311.org/JSON_and_XML_Conversion/

如果您想了解XML到JSON转换的各种约定,可以查看http://wiki.open311.org/JSON_and_XML_Conversion/

One python library that supports more than one convention is xmljson (https://github.com/sanand0/xmljson).

一个支持多个约定的python库是xmljson (https://github.com/sanand0/xmljson)。

#11


0  

edit

编辑

A similar method is advocated on http://www.jsonml.org/. They coined the term json markup language.

在http://www.jsonml.org/提倡使用类似的方法。他们创造了术语json标记语言。


You can pick any mapping you like, but if you map

你可以选择任何你喜欢的映射,但如果你映射。

<el attr="value">
  txt
</el>

to

{"el":{"attr":"value","content":"txt"}}

then how would you map:

那么你会怎么映射呢?

<el attr="value" content="txt1">txt2</el>

I'd make use of the fact that some attibute names are forbidden.

我要利用一些不允许使用的名字这一事实。

{"el":{"attr":"value", "content":"txt1", "":["txt"]}

Or a more compex example:

或者更简单的例子:

<widget>
  <debug>on</debug>
  <window title="Sample Konfabulator Widget">
    I just put some text here
    <name>main_window</name>
    <width>500</width>
    <height>500</height>
  </window>
  <image src="Images/Sun.png" name="sun1">
    <hOffset>250<unit>mm</unit></hOffset>
    <vOffset>250</vOffset>
    <alignment>center</alignment>
  </image>
</widget>

could map to:

可以映射到:

{"widget":{"":[
  {"debug":{"":["on"]}},
  {"window":{"title":"Sample Konfabulator Widget", "": [
    "I just put some text here",
    {"name":{"":["main window"]}},
    {"width":{"":["500"]}},
    {"height":{"":["500"]}}
  ]},
  {"image":{"src":"Images/Sun.png", "name":"sun1", "":[
    {"hOffset":{"":["250",{"unit":{"":["mm"]}}]}},
    {"vOffset":{"":["250"]}},
    {"alignment":{"":["center"]}}
  }
]}

The rules for this conversion are unambiguous:

这种转换的规则是明确的:

  • an element is converted to an object.
  • 元素被转换为对象。
  • The object key is the element name.
  • 对象键是元素名。
  • The object value is an object itself, with:
    • an attibute is mapped to an object property. (key/value)
    • 一个attibute被映射到一个对象属性。(键/值)
    • the object content is mapped to a special property.
      • The special property name is an empty string. This can never collide with an xml attribyte name.
      • 特殊属性名是一个空字符串。这永远不会与xml attribyte名称发生冲突。
      • The special property value is an array.
      • 特殊属性值是一个数组。
      • Within the array, plain text is represented as a string.
      • 在数组中,纯文本表示为字符串。
      • Within the array, elements are represented as objects, as described above.
      • 在数组中,元素被表示为对象,如上所述。
    • 对象内容被映射到一个特殊的属性。特殊属性名是一个空字符串。这永远不会与xml attribyte名称发生冲突。特殊属性值是一个数组。在数组中,纯文本表示为字符串。在数组中,元素被表示为对象,如上所述。
  • 对象值是一个对象本身,带有:一个attibute被映射到一个对象属性。对象内容被映射到一个特殊的属性。特殊属性名是一个空字符串。这永远不会与xml attribyte名称发生冲突。特殊属性值是一个数组。在数组中,纯文本表示为字符串。在数组中,元素被表示为对象,如上所述。

To safe space, there is a way to unambigously simplify mentioned mapping:

对于安全空间,有一种方法可以简单地简化所提到的映射:

{"widget":{"":[
  {"debug":"on"},
  {"window":{"title":"Sample Konfabulator Widget", "": [
    "I just put some text here",
    {"name":"main window"},
    {"width":"500"},
    {"height":"500"}
  ]},
  {"image":{"src":"Images/Sun.png", "name":"sun1", "":[
    {"hOffset":["250",{"unit":"mm"}]},
    {"vOffset":"250"},
    {"alignment":"center"}
  }
]}
  • If an element doesn't have any attibutes, the value object (containing the special empty string mapping to an array) is replaced by the array directly. So instead of:

    如果一个元素没有任何attibutes,则该值对象(包含对数组的特殊空字符串映射)将直接被数组替换。而不是:

    {"hOffset":{"":["250",{"unit":{"":["mm"]}}]}}

    { " hOffset ":{ ":[" 250 ",{“单位”:{ ":[“毫米”]} }]} }

you get

你得到

{"hOffset":["250",{"unit":["mm"]}]}
  • If the element content is just text, the array containing the string value is replaced by the string value directly, so you get:

    如果元素内容只是文本,包含字符串值的数组将被字符串值直接替换,则得到:

    {"hOffset":["250",{"unit":"mm"}]}

    {“hOffset”:[" 250 ",{“单位”:“毫米”}]}

This way, there will always be exactly one way to map the jml (json markup language) back to xml (or html)

这样,将jml (json标记语言)映射回xml(或html)的方法总是一种

#12


-2  

Excluding the attribute names that are always same length, JSON will be always more compact as just does not have closing tags ;)

不包括总是相同长度的属性名,JSON将总是更紧凑,因为没有结束标记;)

#1


15  

Perhaps:

可能:

{
  "folders": [
    { "id":123, "private":0, "archived":0, "order":1, "title":"Shopping" },
    ...
  ]
}

Because there is not an exact correspondence between XML and JSON, you are free (e.g. have to define) how the two data-structures map. For instance, in the above, the "folder" element is implicit in the nested objects in the "folders" array.

因为XML和JSON之间没有确切的对应关系,所以您可以*地(例如必须定义)如何映射这两个数据结构。例如,在上面,“文件夹”元素隐含在“文件夹”数组中的嵌套对象中。

This could be expanded as in:

这可以扩大如下:

"folders": [{"folder": { .... }]

Etc, but there is still the problem of not being able to capture content+attributes as consistently as XML. In any case, your data-structure -> JSON|XML serializer likely works in a particular way (and please, please, use a library, not "hand-rolled" JSON-string-munging). That is; the format of the XML and JSON should be uniformly dictated (somehow) by the data-structure for transmission.

但是仍然存在不能像XML那样一致地捕获内容+属性的问题。无论如何,您的数据结构——> JSON|XML序列化器可能以特定的方式工作(请使用一个库,而不是“手工”JSON-string-munging)。这是;XML和JSON的格式应该由数据结构统一地(以某种方式)进行传输。

#2


11  

You need something like this:

你需要这样的东西:

{
    "folders": {
        "folder":{ 
        "@": {
            "id": "123",
            "private": "0",
            "archived": "0",
            "order": "1"
            },
        "#": "Shopping"
        }
    }
}

At least this works correctly with js2xmlparser.

至少,这在js2xmlparser中是正确的。

#3


7  

An example of how YQL presents XML and the corresponding JSON. No need to know anything about YQL to understand this but if you are interested your can check the YQL console and try it out yourself in the YQL console

YQL如何表示XML和相应的JSON的示例。不需要了解任何有关YQL的知识就可以理解这一点,但是如果您感兴趣,可以检查YQL控制台并在YQL控制台自己尝试它

XML

XML

<results>
    <a href="/">NBA</a>
    <a class="topnav" href="#">TEAMS</a>
    <a href="/teams/">Teams</a>
    <a href="/hawks/">Atlanta</a>

JSON

JSON

"results": {
  "a": [
    {
     "href": "/",
     "content": "NBA"
    },
    {
     "class": "topnav",
     "href": "#",
     "content": "TEAMS"
    },
    {
     "href": "/teams/",
     "content": "Teams"
    },
    {
     "href": "/hawks/",
     "content": "Atlanta"
    },

#4


7  

There is a JSON notation / convention called badgerfish attempts to standardizes (at least its own terms) the way of preserving of most of the low level XML semantics when XML DOM represented as JSON DOM (with attributes of course) (see http://badgerfish.ning.com/).

有一种叫做badgerfish的JSON表示法/约定试图标准化(至少是它自己的术语),当XML DOM表示为JSON DOM(当然包含属性)时,保持大部分低级别XML语义的方法(参见http://badgerfish.ning.com/)。

So you can easily convert back the badgerfishied-json representation to the XML representation and you still work on the structure with your favorite XML toolset (for me its XPATH / QUERY expressions and tools).

因此,您可以轻松地将badgerfi -json表示转换回XML表示,并且仍然使用您最喜欢的XML工具集(对我来说是它的XPATH /查询表达式和工具)处理结构。

It has also easy to memorize syntax rules (total 9) like: "Attributes go in properties whose names begin with @". You can work on badgerfishied-json in the text editor without overloading your neural circuitry unnecessarily. Usually you can memorize them in the first pass.

它还很容易记住语法规则(总共9条),比如:“属性位于名称以@开头的属性中”。您可以在文本编辑器中使用badgerfishie -json,而无需不必要地重载您的神经电路。通常你可以一开始就记住它们。

#5


4  

Could be compact in the JSON too, attribute is just the same as the value inside tag

在JSON中也可以是紧凑的,属性和标签中的值一样吗

from here:

从这里开始:

http://www.json.org/example.html

http://www.json.org/example.html

{"widget": {
    "debug": "on",
    "window": {
        "title": "Sample Konfabulator Widget",
        "name": "main_window",
        "width": 500,
        "height": 500
    },
    "image": { 
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 250,
        "alignment": "center"
    }
}}  

The same text expressed as XML:

用XML表示的同一文本:

<widget>
    <debug>on</debug>
    <window title="Sample Konfabulator Widget">
        <name>main_window</name>
        <width>500</width>
        <height>500</height>
    </window>
    <image src="Images/Sun.png" name="sun1">
        <hOffset>250</hOffset>
        <vOffset>250</vOffset>
        <alignment>center</alignment>
    </image>
</widget>

#6


4  

It seems to me that the most exact correspondence between XML and JSON would need to represent an XML node as a triplet (i.e. array): [name, attributes, value], with name being a string, attributes an object with attribute names as keys and attribute values as (string) values, and value a string (for atomic values) or an array of such triplets.

在我看来,最准确的对应的XML和JSON需要代表XML节点三联体(即数组):名称、属性值,名字是一个字符串,一个对象属性与属性名称作为键和属性值(字符串)值,和价值一个字符串(对于原子值)或一个数组的三胞胎。

By such mapping the JSON-equivalent of

通过这样的映射,json等价于

<folders>
    <folder id="123" private="0" archived="0" order="1">Shopping</folder>
</folders>

would be

[  "folders",
   {}, 
   [
      [  "folder", 
         {   "id": "123",
             "private": "0",
             "archived": "0",
             "order": "1"
         },
         "Shopping"
      ]
   ]
]

Actually the idea behind this mapping is that:

实际上,这个映射背后的想法是:

1) XML-JSON transformation be reversible. 2) The "sibling" relationship of sub-nodes be preserved

1) XML-JSON转换是可逆的。2)保留子节点的“兄弟”关系

At the same time the distinction between attribute nodes and value nodes is explicit here.

与此同时,属性节点和值节点之间的区别是显而易见的。

Does it make sense? And does it justify the complexity overhead?

它有意义吗?它是否证明复杂性开销是合理的?

#7


0  

JSON is more uniform than XML and doesn't distinguish between plain-text attributes and hierarchical contents. The natural representation for your example would be

JSON比XML更统一,不区分纯文本属性和分层内容。您的示例的自然表示形式是

[
  {"id": 123, "private": 0, "archived": 0, "order": 1, "name": "Shopping"}
]

This is still more compact than the respective XML.

这仍然比各自的XML更紧凑。

#8


0  

"content" is used for the actual text, while the attributes are its siblings in the resulted JSON:

“content”用于实际的文本,而属性是其结果JSON中的兄弟属性:

{ "folders":
 { "folder":
  {
   "archived":0,
   "private":0,
   "id":123,
   "content":"Shopping",
   "order":1
  }
 }
}

Java implementation details

Java实现细节

#9


0  

I've ran into a scenario that needs both XML and JSON for input and output based on what was being passed in. I found a way that works with XML Attributes/Properties and JSON. Now note, it's how it coded in Java, makes it work this way.

我遇到了一个场景,根据传入的内容,输入和输出都需要XML和JSON。我找到了一种处理XML属性/属性和JSON的方法。注意,它是用Java编写的,它是这样工作的。

My XML Example:

我的XML示例:

<Log>
    <datetime>05/05/2017 13:45:22</datetime>
    <sessionid>2da236d2-3852-4a09-8067-198193d2828b</sessionid>
    <message msgType="Debug">This is my message</message>
</Log>

My JSON Example:

我的JSON的例子:

{
    "datetime":"05/05/2017 13:45:22",
    "sessionid":"2da236d2-3852-4a09-8067-198193d2828b",
    "message": {
        "content":"This is a testa",
        "msgType":"Debug"
    }
}

How I made it work via code Log.java:

我是如何通过代码日志来工作的。

package log;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

@JacksonXmlRootElement(localName = "Log")
public class Log {
    @JacksonXmlProperty(localName = "datetime")
    private String datetime;
    @JacksonXmlProperty(localName = "sessionid")
    private String sessionid;
    @JacksonXmlProperty(localName = "message")
    private Message message;

    public Log() {
        this.sessionid = "0";
        this.datetime = "";
        this.message = new Message();
    }

    public String getDatetime() {
        return datetime;
    }

    public void setDatetime(String datetime) {
        this.datetime = datetime;
    }

    public String getSessionid() {
        return sessionid;
    }

    public void setSessionid(String sessionid) {
        this.sessionid = sessionid;
    }

    public Message getMessage() {
        return message;
    }

    public void setMessage(Message message) {
        this.message = message;
    }
}

Message.java, Note the @JacksonXmlText below, which is key:

消息。请注意下面的@JacksonXmlText,这是关键:

package log;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;

public class Message {
    @JacksonXmlProperty(localName = "msgType", isAttribute = true)
    private String msgType;
    @JacksonXmlText
    private String content;

    public Message() {
        this.content = "";
    }

    public String getMsgType() {
        return msgType;
    }

    public void setMsgType(String msgType) {
        switch(msgType.toLowerCase())
        {
        case "test":
        case "debug":
        case "warn":
        case "error":
            break;
        default:
            msgType = "Unknown";
            break;
        }

        this.msgType = msgType;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

Caller within LogController.java:

调用者在LogController.java:

..
@RequestMapping(value = "/Logger", produces={"application/xml", "application/json"}, consumes={"application/xml", "application/json"})
public ResponseEntity<String> Logger(@RequestBody String logInfo, @RequestHeader("Content-Type") String contentType) {
    try 
    {
        String xml = "";
        Log logObj = null; 
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.add("Content-Type", contentType);

        if (contentType.toLowerCase().contains("json"))
        {
           ObjectMapper mapper = new ObjectMapper();
           logObj = mapper.readValue(logInfo, Log.class);
           xml = mapper.writeValueAsString(logObj);
        }
        else if (contentType.toLowerCase().contains("xml"))
        {
           XmlMapper xmlMapper = new XmlMapper();
           logObj = xmlMapper.readValue(logInfo, Log.class);
           xml = xmlMapper.writeValueAsString(logObj);
        }
        else
           return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);

        //TODO GWL
        //Save Log data, via Async Web Service, Data, or System 
        return new ResponseEntity<String>(xml, responseHeaders, HttpStatus.OK);
    } 
    catch( Exception ex)
    {
        ex.printStackTrace();
        return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
    }
}

#10


0  

If you like to have an overview of the various conventions for XML to JSON conversion, there is a nice overview at: http://wiki.open311.org/JSON_and_XML_Conversion/

如果您想了解XML到JSON转换的各种约定,可以查看http://wiki.open311.org/JSON_and_XML_Conversion/

One python library that supports more than one convention is xmljson (https://github.com/sanand0/xmljson).

一个支持多个约定的python库是xmljson (https://github.com/sanand0/xmljson)。

#11


0  

edit

编辑

A similar method is advocated on http://www.jsonml.org/. They coined the term json markup language.

在http://www.jsonml.org/提倡使用类似的方法。他们创造了术语json标记语言。


You can pick any mapping you like, but if you map

你可以选择任何你喜欢的映射,但如果你映射。

<el attr="value">
  txt
</el>

to

{"el":{"attr":"value","content":"txt"}}

then how would you map:

那么你会怎么映射呢?

<el attr="value" content="txt1">txt2</el>

I'd make use of the fact that some attibute names are forbidden.

我要利用一些不允许使用的名字这一事实。

{"el":{"attr":"value", "content":"txt1", "":["txt"]}

Or a more compex example:

或者更简单的例子:

<widget>
  <debug>on</debug>
  <window title="Sample Konfabulator Widget">
    I just put some text here
    <name>main_window</name>
    <width>500</width>
    <height>500</height>
  </window>
  <image src="Images/Sun.png" name="sun1">
    <hOffset>250<unit>mm</unit></hOffset>
    <vOffset>250</vOffset>
    <alignment>center</alignment>
  </image>
</widget>

could map to:

可以映射到:

{"widget":{"":[
  {"debug":{"":["on"]}},
  {"window":{"title":"Sample Konfabulator Widget", "": [
    "I just put some text here",
    {"name":{"":["main window"]}},
    {"width":{"":["500"]}},
    {"height":{"":["500"]}}
  ]},
  {"image":{"src":"Images/Sun.png", "name":"sun1", "":[
    {"hOffset":{"":["250",{"unit":{"":["mm"]}}]}},
    {"vOffset":{"":["250"]}},
    {"alignment":{"":["center"]}}
  }
]}

The rules for this conversion are unambiguous:

这种转换的规则是明确的:

  • an element is converted to an object.
  • 元素被转换为对象。
  • The object key is the element name.
  • 对象键是元素名。
  • The object value is an object itself, with:
    • an attibute is mapped to an object property. (key/value)
    • 一个attibute被映射到一个对象属性。(键/值)
    • the object content is mapped to a special property.
      • The special property name is an empty string. This can never collide with an xml attribyte name.
      • 特殊属性名是一个空字符串。这永远不会与xml attribyte名称发生冲突。
      • The special property value is an array.
      • 特殊属性值是一个数组。
      • Within the array, plain text is represented as a string.
      • 在数组中,纯文本表示为字符串。
      • Within the array, elements are represented as objects, as described above.
      • 在数组中,元素被表示为对象,如上所述。
    • 对象内容被映射到一个特殊的属性。特殊属性名是一个空字符串。这永远不会与xml attribyte名称发生冲突。特殊属性值是一个数组。在数组中,纯文本表示为字符串。在数组中,元素被表示为对象,如上所述。
  • 对象值是一个对象本身,带有:一个attibute被映射到一个对象属性。对象内容被映射到一个特殊的属性。特殊属性名是一个空字符串。这永远不会与xml attribyte名称发生冲突。特殊属性值是一个数组。在数组中,纯文本表示为字符串。在数组中,元素被表示为对象,如上所述。

To safe space, there is a way to unambigously simplify mentioned mapping:

对于安全空间,有一种方法可以简单地简化所提到的映射:

{"widget":{"":[
  {"debug":"on"},
  {"window":{"title":"Sample Konfabulator Widget", "": [
    "I just put some text here",
    {"name":"main window"},
    {"width":"500"},
    {"height":"500"}
  ]},
  {"image":{"src":"Images/Sun.png", "name":"sun1", "":[
    {"hOffset":["250",{"unit":"mm"}]},
    {"vOffset":"250"},
    {"alignment":"center"}
  }
]}
  • If an element doesn't have any attibutes, the value object (containing the special empty string mapping to an array) is replaced by the array directly. So instead of:

    如果一个元素没有任何attibutes,则该值对象(包含对数组的特殊空字符串映射)将直接被数组替换。而不是:

    {"hOffset":{"":["250",{"unit":{"":["mm"]}}]}}

    { " hOffset ":{ ":[" 250 ",{“单位”:{ ":[“毫米”]} }]} }

you get

你得到

{"hOffset":["250",{"unit":["mm"]}]}
  • If the element content is just text, the array containing the string value is replaced by the string value directly, so you get:

    如果元素内容只是文本,包含字符串值的数组将被字符串值直接替换,则得到:

    {"hOffset":["250",{"unit":"mm"}]}

    {“hOffset”:[" 250 ",{“单位”:“毫米”}]}

This way, there will always be exactly one way to map the jml (json markup language) back to xml (or html)

这样,将jml (json标记语言)映射回xml(或html)的方法总是一种

#12


-2  

Excluding the attribute names that are always same length, JSON will be always more compact as just does not have closing tags ;)

不包括总是相同长度的属性名,JSON将总是更紧凑,因为没有结束标记;)