How would I express XML tag attributes in JSON?

后端 未结 13 2174
遥遥无期
遥遥无期 2020-12-07 20:35

I am designing an API for my webapp.

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

But I have just bumped to this XML:

相关标签:
13条回答
  • 2020-12-07 21:15

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

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

    Java implementation details

    0 讨论(0)
  • 2020-12-07 21:16

    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.

    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.

    0 讨论(0)
  • 2020-12-07 21:16

    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/).

    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).

    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.

    0 讨论(0)
  • 2020-12-07 21:20

    This approach supports inverse transformation to XML:

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

    It works correctly with js2xmlparser.

    0 讨论(0)
  • 2020-12-07 21:20

    My choice for XML representation, to make sure it's somehow reversible, is as follows (using your example):

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

    translates to:

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

    So by using @ as an indicator for "attribute" and $t as indicator for "text content" I can revert the JSON string to a faithful version of the original XML.

    A nice Node package to perform this conversion is XML2JSON, although it doesn't do anything special with the attributes, and some extra code is required to produce this output.

    0 讨论(0)
  • 2020-12-07 21:20

    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.

    My XML Example:

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

    {
        "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:

    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:

    ..
    @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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题