JSON, соответствующий XML с атрибутами? - PullRequest
29 голосов
/ 30 октября 2010

Я разрабатываю API для моего веб-приложения.

Я думал о поддержке только ответов JSON (не XML), потому что они более упорядочены.

Но я только что столкнулся с этим XML:1005 *

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

и мне было интересно, каким будет соответствующий JSON.У меня такое ощущение, что в этом случае XML будет более компактным.

Спасибо, Дэн

Ответы [ 14 ]

19 голосов
/ 30 октября 2010

Возможно:

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

Поскольку не точное соответствие между XML и JSON, вы свободны (например, должны определить), как отображаются две структуры данных. Например, как указано выше, элемент «папка» неявно присутствует во вложенных объектах в массиве «папки».

Это может быть расширено так:

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

и т. Д., Но все еще существует проблема в том, что не может захватывать контент + атрибуты так же последовательно, как XML. В любом случае, ваша структура данных -> JSON | XML-сериализатор, скорее всего, работает определенным образом (и , пожалуйста, используйте библиотеку, а не "свернутую вручную" JSON-string-munging ). То есть; формат XML и JSON должен определенным образом (как-то) диктоваться структурой данных для передачи.

15 голосов
/ 11 июня 2015

Этот подход поддерживает обратное преобразование в XML:

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

Работает правильно с js2xmlparser .

7 голосов
/ 26 мая 2013

Существует нотация / соглашение JSON под названием badgerfish пытается стандартизировать (по крайней мере, свои собственные термины) способ сохранения большинства низкоуровневой семантики XML, когда XML DOM представлен как JSON DOM (с атрибутами).конечно) (см. http://badgerfish.ning.com/).

Так что вы можете легко преобразовать обратно представление badgerfishied-json в представление XML, и вы все еще работаете над структурой с вашим любимым набором инструментов XML (для меня)это XPATH / QUERY выражения и инструменты).

Также легко запомнить правила синтаксиса (всего 9), например: "Атрибуты идут в свойствах, имена которых начинаются с @" . Вы можете работатьна badgerfishied-json в текстовом редакторе, не перегружая ваши нервные схемы без необходимости. Обычно вы можете запомнить их в первом проходе.

7 голосов
/ 30 октября 2010

Пример того, как 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"
    },
4 голосов
/ 09 января 2015

Мне кажется, что наиболее точное соответствие между XML и JSON должно представлять узел XML в виде триплета (т. Е. Массива): [имя, атрибуты, значение], где имя является строкой, атрибуты объекта с атрибутом имена в качестве ключей и значения атрибутов в виде (строковых) значений и значение строки (для атомарных значений) или массива таких триплетов.

При таком отображении 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) Отношения «одноуровневых» подузлов должны быть сохранены

В то же время различие между узлами атрибута и узлами значения здесь явно.

Имеет ли это смысл? И оправдывает ли это сложность накладных расходов?

4 голосов
/ 30 октября 2010

Может также быть компактным в 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>
1 голос
/ 05 мая 2018

редактировать

Подобный метод защищен на 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"}
  }
]}
  • Если элемент не имеет каких-либо атрибутов, объект-значение (содержащий специальное отображение пустой строки в массив) заменяется непосредственно на массив. Так что вместо:

    { "hOffset": { "": [ "250", { "единица": { "": [ "мм"]}}]}}

вы получите

{"hOffset":["250",{"unit":["mm"]}]}
  • Если содержимое элемента представляет собой просто текст, массив, содержащий строковое значение, заменяется непосредственно строковым значением, поэтому вы получите:

    * * {Тысячи семьдесят-одна "hOffset": [ "250", { "единица": "мм"}]} * ** 1073 тысячи семьдесят две *

Таким образом, всегда будет только один способ отобразить jml (язык разметки json) обратно в xml (или html)

0 голосов
/ 21 июня 2019

Мой выбор для представления 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 в качестве индикатора для «текстового содержимого», я могу вернуть строку JSON в достоверную версию исходного XML.

Хорошим пакетом Node для выполнения этого преобразования является XML2JSON , хотя он не делает ничего особенного с атрибутами, и для получения этого вывода требуется дополнительный код.

0 голосов
/ 14 августа 2018

Вступительное слово: В этом ответе я намеренно отстаю от первоначального вопроса и несколько расширяю сферу.Иногда, чтобы задать вопрос, стоящий за вопросом, нам нужно сначала взглянуть на общую картину.

Так же, как все животные равны, все переводы из JSON в XML и из XML в JSON неравны.Не может быть математически правильных ответов на этот вопрос, и даже если они есть, они могут быть неправильными.Все ответы будут зависеть от мнения и зависят от конкретных вариантов использования.

JSON и XML поддерживают и опускают концепции, которые затрудняют совершенные, обратимые и собственные переводы.

Чтобы назвать только некоторые из них:

  • XML требует корневого элемента.JSON нет.

  • XML различает элементы и атрибуты.Атрибуты - это листья, элементы могут быть листьями или ветвями.Объекты JSON близки к элементам, но не имеют прямого эквивалента для атрибутов.

  • JSON имеет массивы;ближайший эквивалент XML - это родительский элемент, но некоторые переводы нарушаются, когда есть только один дочерний элемент.

  • XML имеет пространства имен… .. Чем меньше сказано о тех, тем лучше…

  • JSON должен быть компактным и легким и ближе (по моему скромному мнению) к YAML, чем к XML.

Там, где существует концепцияИсходный язык, но не на целевом языке, мы должны быть изобретательными и креативными в нашем переводе.Ваши варианты использования являются ключевыми.

например,

  • Должен ли результат быть как можно более родным на целевом языке?Будем ли мы моделировать это в JSON?Будем ли мы моделировать это в XML?

  • Должен ли результат быть обратимым к исходному источнику, даже за счет «нативного ощущения»?

  • Является ли компактность критерием?Это может иметь место для JSON над XML-элементом с большим количеством элементов, но не для JSON, переведенного из XML и предназначенного для обратного перевода.

Для сравнения с человеческими языками: на швейцарскомНемецкий язык, мы любим наши уменьшительные: существительные обычно сокращаются до маленькой формы, где это было бы странно на английском языке;но еще более странно, у нас есть уменьшительные глаголы!

Так что «wir machen es köchele», технически, можно перевести как «мы будем немного готовить» или «мы немного готовим», но любой из них будет плохими неправильный английский, и каким-то образом упустить идею.

«мы приготовим вкусное блюдо» или «мы немного повеселимся готовить» было бы намного ближе к первоначальной идее.Но я подозреваю, что Антея Белл (известность перевода с Asterix на английский) действительно поняла бы смысл;«Давайте приготовим пир…».

Вернуться к исходному вопросу.У программистов Python есть концепция pythonesque: = наиболее подходящая для основного духа python.Ответ пользователя 166390 (принятый ответ во время этого ответа) кажется мне наиболее JSONesque.

0 голосов
/ 06 мая 2017

Если вы хотите получить обзор различных соглашений для преобразования XML в JSON, есть хороший обзор по адресу: http://wiki.open311.org/JSON_and_XML_Conversion/

Одна библиотека Python, которая поддерживает более одного соглашения, - это xmljson (https://github.com/sanand0/xmljson).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...