Je FORMULEES cela, récemment:
(juste une expérience de pensée)
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)
justification rapide:
éléments XML sont le seul type de noeud (à côté de la racine du document) qui accepte le contenu mixte (nœuds de texte et/ou d'autres éléments, commentaires, PI, et définit un ordre de ses nœuds enfants, d'où le e des tableaux JSON (les index enfants étant alors basés sur 1, au lieu de 0, en raison de l'index réservé 0 pour porter le type de nœud (élément) info; mais on peut noter que les nodesets XPath utilisent aussi un index basé sur 1, btw);
Les cartes de nom/valeur d'attribut XML n'ont pas besoin d'être classées par ordre (noms d'attribut) par rapport à. leur élément propriétaire, uniquement l'unicité de ceux de ce nœud d'élément; d'où l'utilisation d'un objet JSON à l'index 0 du tableau conteneur (correspondant à l'élément owner); Après tout, alors que "" est une clé JSON parfaitement valide dans les valeurs d'objet, il est également vrai que ni les éléments XML ni les attributs ne peuvent avoir un nom vide de toute façon ... d'où l'utilisation de "" en tant que clé spéciale spéciale, pour fournir le nom de l'élément.
Et voici ce qu'il faut pour le transformer en HTML en utilisant mon petit "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('"', """) })
);
}
}
return tag.join(" ");
}
],
[ [ function/*Text*/(node) { return typeof node === "string"; } ],
function(text) {
return text.
replace("\t", "&x09;").
replace("\n", "&x0A;").
replace("\r", "&x0D;");
}
]
] };
(Cf. https://jsfiddle.net/YSharpLanguage/dzq4fe39/1)
où,
Per(tinyInfosetJSLT).map(someTinyInfosetSample)
donne (sous forme de chaîne):
<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>
(mais surtout la transformation pourrait également être facilement adapté pour utiliser une usine de nœud DOM, et de construire un document DOM réel, au lieu de construire une chaîne)
« HTH,
Pourquoi l'ordre importe quand vous avez converti le XML en JSON? L'ordre des nœuds n'est-il pas spécifique à XML? – Cerebrus