source

XML 태그 속성을 JSON으로 어떻게 표현합니까?

nicesource 2023. 3. 10. 22:08
반응형

XML 태그 속성을 JSON으로 어떻게 표현합니까?

저는 웹앱 API를 디자인하고 있습니다.

JSON 응답(XML이 아닌)만 지원하려고 했습니다.왜냐하면 합리화되었기 때문입니다.

그런데 방금 이 XML을 접했습니다.

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

대응하는 JSON이 어떨까 해서이 경우 XML이 더 콤팩트할 것 같습니다.

아마도:

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

XML과 JSON은 정확하게 대응하고 있지 않기 때문에, 2개의 데이터 구조가 어떻게 매핑되는지를 정의할 필요가 있습니다(예를 들면, 정의해야 합니다).예를 들어 위의 경우 "폴더" 요소는 "폴더" 배열의 중첩된 개체에 암묵적으로 포함되어 있습니다.

이는 다음과 같이 확장할 수 있습니다.

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

etc. 단, XML만큼 일관되게 컨텐츠+속성을 캡처할 수 없는 문제가 있습니다.어느 경우든 데이터 구조 -> JSON|XML 시리얼라이저는 특정 방법으로 동작합니다(JSON 스트링-mung이 아닌 라이브러리를 사용하십시오).즉, XML 및 JSON의 형식은 데이터 구조에 의해 (어떤 식으로든) 균일하게 지시되어야 합니다.

이 접근방식은 XML로의 역변환을 지원합니다.

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

js2xmlparser에서 올바르게 동작합니다.

XML DOM이 JSON DOM(물론 속성 포함)으로 표현될 때 낮은 수준의 XML 시멘틱 대부분을 보존하는 방법(최소한 자체 용어)을 표준화하려는 JSON 표기법/규칙이 있습니다(http://badgerfish.ning.com/) 참조).

따라서 badgerfished-json 표현을 XML 표현으로 쉽게 변환할 수 있으며, 마음에 드는 XML 도구 세트(XPATH/QUERY 표현식 및 도구)를 사용하여 구조 작업을 수행할 수 있습니다.

또한 "속성은 이름이 @로 시작하는 속성에 들어갑니다"와 같은 구문 규칙(합계 9)을 쉽게 기억할 수 있습니다.신경 회로에 불필요한 부하를 주지 않고 텍스트 편집기에서 오더피시드 json 작업을 수행할 수 있습니다.보통 첫 번째 패스로 외울 수 있어요.

YQL이 XML 및 대응하는 JSON을 표시하는 방법의 예.이를 이해하기 위해 YQL에 대해 알 필요는 없지만 관심이 있는 경우 YQL 콘솔을 확인하고 YQL 콘솔에서 직접 사용해 보십시오.

XML

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

JSON

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

XML과 JSON의 가장 정확한 대응관계는 XML 노드를 트리플렛(어레이 등)으로 나타낼 필요가 있다고 생각합니다.[ name , attributes , value ]이름을 문자열로 하여 속성명을 키로 하여 속성값을 (string) 값으로 하여 문자열(atomic 값의 경우) 또는 이러한 세 개의 배열을 지정합니다.

이러한 매핑에 의해, JSON에 상당합니다.

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

되지요

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

실제로 이 매핑의 배후에 있는 아이디어는 다음과 같습니다.

1) XML-JSON 변환은 되돌릴 수 있다.2) 서브노드의 "sibling" 관계가 유지된다.

동시에 속성 노드와 값 노드 간의 구분이 여기서 명확합니다.

그게 말이 되는 건가요?그리고 그것이 복잡성의 오버헤드를 정당화합니까?

JSON에서도 컴팩트할 수 있습니다.속성은 내부 태그의 값과 동일합니다.

여기서부터:

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"
    }
}}  

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>

XML 표현은 원래대로 되돌릴 수 있도록 하기 위해 다음과 같이 선택합니다(예시 사용).

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

번역자:

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

'이렇게'를 @'위험'을 나타내는 지표로서$t「 content 의 한 버전으로 수 있습니다

이 변환을 수행하기 위한 적절한 노드 패키지는 XML2JSON이지만, 이 속성에는 특별한 작업이 없으며, 이 출력을 생성하려면 몇 가지 추가 코드가 필요합니다.

편집하다

http://www.jsonml.org/ 에서도 같은 방법이 권장되고 있습니다.그들은 json 마크업 언어라는 용어를 만들었다.


원하는 맵을 선택할 수 있지만 맵을 작성하면

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

로.

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

그럼 어떻게 매핑하시겠습니까?

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

나는 몇몇 아트리뷰트 이름이 금지되어 있다는 사실을 이용하고 싶다.

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

또는 보다 콤펙스적인 예:

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

매핑처:

{"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"]}}
  }
]}

이 변환의 규칙은 명확합니다.

  • 요소가 객체로 변환됩니다.
  • 오브젝트 키는 요소 이름입니다.
  • 오브젝트 값은 오브젝트 자체이며 다음 항목이 있습니다.
    • 속성은 오브젝트 속성에 매핑됩니다.(키/값)
    • 오브젝트 콘텐츠는 특정 속성에 매핑됩니다.
      • 특수 속성 이름이 빈 문자열입니다.이것은 xml 속성 이름과 충돌할 수 없습니다.
      • 특수 속성 값은 배열입니다.
      • 배열 내에서 일반 텍스트는 문자열로 표시됩니다.
      • 배열 내에서 요소는 위에서 설명한 바와 같이 개체로 표시됩니다.

공간을 보호하기 위해 언급한 매핑을 명확하게 단순화하는 방법이 있습니다.

{"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"}
  }
]}
  • 요소에 속성이 없는 경우 값 개체(배열에 대한 특수 빈 문자열 매핑 포함)가 배열로 직접 대체됩니다.그래서 다음 대신:

    {"오프셋":{":["250",{"단위:{":["mm"]}}}}}}:

얻을 수 있다

{"hOffset":["250",{"unit":["mm"]}]}
  • 요소의 내용이 텍스트일 경우 문자열 값을 포함하는 배열이 문자열 값으로 직접 대체되므로 다음과 같은 결과를 얻을 수 있습니다.

    {"오프셋":["250", {"단위":mm"}}

이렇게 하면 jml(json 마크업 언어)을 xml(또는 html)에 매핑하는 방법은 항상 한 가지뿐입니다.

JSON은 XML보다 균일하며 일반 텍스트 속성과 계층적 내용을 구분하지 않습니다.이 예제의 자연스러운 표현은 다음과 같습니다.

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

이것은 각 XML보다 더 콤팩트합니다.

실제 텍스트에는 "content"가 사용되며, 결과 JSON에서는 속성이 해당 형제입니다.

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

Java 구현 상세

전달된 내용에 따라 입력과 출력에 XML과 JSON이 모두 필요한 시나리오가 있습니다.XML Attributes/Properties 및 JSON에서 사용할 수 있는 방법을 찾았습니다.Java에서 코드화된 방식입니다. 이렇게 동작합니다.

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

JSON의 예:

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

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;
    }
}

메시지java, 다음 @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;
    }
}

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);
    }
}

첫 번째 경고:이 답변에서는 일부러 원래의 질문에서 물러서서 범위를 다소 넓히고 있습니다.때때로 질문 뒤에 있는 질문을 하기 위해서는 먼저 큰 그림을 볼 필요가 있다.

모든 동물이 동일하듯이 JSON에서 XML로, XML에서 JSON으로 모든 변환이 동일하지 않습니다.이 질문에는 수학적으로 정답이 있을 수 없으며, 있다 하더라도 틀릴 수 있습니다.모든 답변은 의견의 문제이며 정확한 사용 사례에 따라 달라집니다.

JSON과 XML은 모두 완벽하고 가역적이며 네이티브한 번역을 어렵게 하는 개념을 지원 및 생략합니다.

몇 가지 예를 들면:

  • XML에는 루트 요소가 필요합니다.JSON은 하지 않습니다.

  • XML은 요소와 속성을 구분합니다.속성은 잎이며 요소는 잎 또는 가지일 수 있습니다.JSON 개체는 요소에 가깝지만 속성에 직접 해당하는 개체는 없습니다.

  • JSON에는 어레이가 있습니다.가장 가까운 XML 대응 요소는 부모 요소이지만 하위 요소가 하나뿐인 경우 일부 변환이 위반됩니다.

  • XML에는 네임스페이스가 있습니다.이러한 것에 대해서는, 적게 말할수록 좋습니다.

  • JSON은 콤팩트하고 경량화를 목적으로 하고 있으며 XML보다는 YAML에 가깝다고 생각합니다.

원어민 언어로 개념이 존재하지만 대상 언어가 아닌 경우에는 창의적이고 창의적인 번역이 필요합니다.고객의 유스케이스가 열쇠입니다.

예.

  • 결과는 대상 언어로 가능한 한 원어민이어야 합니까?JSON에서 이렇게 모델화 할 수 있나요?XML에서는 이렇게 모델화할 수 있습니까?

  • 그 결과는 "원래의 느낌"을 희생하더라도 원래 소스로 되돌릴 수 있어야 하는가?

  • 콤팩트함이 기준입니까?이는 요소 부하가 높은 XML 상의 JSON의 경우일 수 있지만 XML에서 변환되어 다시 변환되도록 설계된 JSON의 경우일 수 없습니다.

인간의 언어와 비교하려면:스위스 독일어로 우리는 우리의 소형어를 사랑한다.명사는 일상적으로 영어에서는 이것이 이상할 수 있는 작은 형태로 축소된다; 하지만 더 비지니스적으로, 우리는 동사의 축소형을 가지고 있다!

즉, "wir machen es köchelle"은 기술적으로 "we will we will little" 또는 "we do little"로 번역될 수 있지만, 서툴고 잘못된 영어로 번역될 수 있으며, 왠지 그 생각을 놓칠 수 있습니다.

'요리를 좀 하겠습니다'나 '요리를 재밌게 하겠습니다'가 원래 아이디어에 훨씬 가까울 것 같아요.하지만 Anthea Bell(Asterix-to-English 번역명사)이 정말로 요점을 알 것 같습니다. "요리하자…"

원래 질문으로 돌아가겠습니다.Python 프로그래머들은 Python의 핵심 기질에 가장 적합한 =라는 피톤스크 개념을 가지고 있습니다.유저 166390(이 회답의 시점에서 받아들여지고 있는 회답)에 의한 회답은, 가장 JSONesque라고 생각됩니다.

항상 같은 길이의 Atribute 이름을 제외하고, JSON은 닫는 태그가 없기 때문에 항상 컴팩트합니다.

언급URL : https://stackoverflow.com/questions/4056419/how-would-i-express-xml-tag-attributes-in-json

반응형