вызов карт XML от JSON - PullRequest
6 голосов
/ 12 мая 2009

На первый взгляд, я подумал, что использовать данные XML в javascript будет так же просто, как найти библиотеку xml-to-json и превратить мой XML в дерево объектов JavaScript.

Однако теперь я понимаю, что в xml можно создавать структуры, которые не отображаются непосредственно в json.

В частности, это:

<parentNode>
    <fooNode>data1</fooNode>
    <barNode>data2</barNode>
    <fooNode>data3</fooNode>
</parentNode>

Инструменты xml-to-json, которые я нашел, преобразуют предыдущие в что-то вроде этого:

{
parentnode:{
    foonode:[
        'data1',
        'data3'
    ],
    barnode:'data2'
}

}

, в котором порядок дочерних узлов был изменен. Мне нужно сохранить порядок моих дочерних узлов. У любого есть более элегантное решение, чем

а) отказ от идеи автоматического преобразования и просто разработка собственной структуры объектов javascript и написание кода для обработки этой конкретной XML-схемы

или

b) вообще отказаться от идеи какого-либо преобразования и оставить мои данные xml в виде документа xml, который я затем перейду.

Ответы [ 4 ]

3 голосов
/ 06 сентября 2013

Существуют установленные преобразования из XML в JSON с ограничениями (см. Преобразование между XML и JSON ) и отображения из JSON в XML (см. JSONx как , определенный здесь и правила конвертации от IBM ). Однако отображение из XML в JSON, сохраняющее порядок, еще не определено. Чтобы полностью охватить все аспекты XML, необходимо выразить XML Infoset в JSON. если вы заботитесь только об элементах XML (без инструкций по обработке и т. д.), я бы выбрал следующую структуру:

[
  "parentNode",
  { } /* attributes */
  [ 
    [ "fooNode", { }, [ "data1" ] ]
    [ "fooNode", { }, [ "data2" ] ]
    [ "fooNode", { }, [ "data3" ] ]
  ]
]

Я реализовал то же отображение, что и отображение между структурами данных XML и Perl, которые похожи на JSON с XML :: Struct . Структура далее соответствует абстрактной модели данных MicroXML , упрощенного подмножества XML.

2 голосов
/ 12 мая 2009

Если вам часто нужно одно и то же имя элемента и вы хотите упорядочить его, возможно, лучше остаться с XML. Какие преимущества вы ожидаете от использования JSON?

1 голос
/ 12 мая 2009

Почему бы не попробовать:

{ parentNode: [
  ["fooNode", "data1"],
  ["barNode", "data2"],
  ["fooNode", "data3"] ]
}

Я думаю, это более или менее решит проблему.

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

0 голосов
/ 05 марта 2016

Недавно я разработал это:

(просто мысленный эксперимент)

var someTinyInfosetSample = {
  "doctype": "html",
  "$": [
    { "": "html" },
    [ { "": "head" },
       [ { "": "title" }, "Document title" ]
    ],
    [ { "": "body" },
      [ { "": "h1" }, "Header 1" ],
      [ { "": "p", "class": "content" },
        "Paragraph... (line 1)", [ { "": "br" } ],
        "... continued (line 2)"
      ]
    ]
  ] };

(при https://jsfiddle.net/YSharpLanguage/dzq4fe39)

Краткое обоснование:

Элементы XML являются единственным типом узла (кроме корня документа), который принимает смешанное содержимое (текстовые узлы и / или другие элементы, комментарии, PI и определяет порядок своих дочерних узлов, поэтому используется массив JSON (дочерний элемент) тогда индексы основаны на 1, а не на 0, поскольку зарезервированный индекс 0 содержит информацию о типе (элементе) узла, но можно заметить, что наборы узлов XPath также используют индекс на основе 1, кстати);

Для карт имен / значений атрибутов XML не требуется упорядочивать ключи (имена атрибутов) по сравнению с. их владелец элемента, только уникальность тех на этом элементе узла; следовательно, использование объекта JSON с индексом 0 массива контейнера (соответствует элементу owner);

и, наконец, в конце концов, хотя "" является совершенно допустимым ключом JSON в значениях объектов, это также тот случай, когда ни элементы XML, ни атрибуты не могут иметь пустое имя в любом случае ... следовательно, использование "" в качестве специального , обычный ключ, для предоставления имени элемента.

И вот что нужно, чтобы превратить его в HTML, используя мой маленький "JSLT" (на https://jsfiddle.net/YSharpLanguage/c7usrpsL/10):

var tinyInfosetJSLT = { $: [
  [ [ function/*Root*/(node) { return node.$; } ],
      function(root) { return Per(this).map(root.$); }
  ],
  [ [ function/*Element*/(node) { return { }.toString.call(node) === "[object Array]"; } ],
      function(element) {
        var children = (element.length > 1 ? element.slice(1) : null),
            startTag = element[0],
            nodeName = startTag[""],
            self = this;
        return children ?
               Per("\r\n<{stag}>{content}</{etag}>\r\n").map
               ({
                 stag: Per(this).map(startTag),
                 etag: nodeName,
                 content: Per(children).map(function(child) { return Per(self).map(child); }).join("")
               })
               :
               Per("<{stag}/>").map({ stag: Per(this).map(startTag) });
      }
  ],
  [ [ function/*StartTag*/(node) { return node[""]; } ],
      function(startTag) {
        var tag = [ startTag[""] ];
        for (var attribute in startTag) {
          if (attribute !== "") {
            tag.push
            (
              Per("{name}=\"{value}\"").
              map({ name: attribute, value: startTag[attribute].replace('"', "&quot;") })
            );
          }
        }
        return tag.join(" ");
      }
  ],
  [ [ function/*Text*/(node) { return typeof node === "string"; } ],
      function(text) {
        return text.
               replace("\t", "&x09;").
               replace("\n", "&x0A;").
               replace("\r", "&x0D;");
      }
  ]
] };

(ср. https://jsfiddle.net/YSharpLanguage/dzq4fe39/1)

, где

Per(tinyInfosetJSLT).map(someTinyInfosetSample)

выход (в виде строки):

<html>
<head>
<title>Document title</title>
</head>

<body>
<h1>Header 1</h1>

<p class="content">Paragraph... (line 1)<br/>... continued (line 2)</p>
</body>
</html>

(но выше преобразование также может быть легко адаптировано для использования фабрики узлов DOM и построения фактического документа DOM вместо построения строки)

НТН,

...