J'essaie de mapper HTML en JSON avec une structure intacte. Y a-t-il des bibliothèques qui font cela ou devrai-je écrire la mienne? Je suppose que s’il n’ya pas de bibliothèques html2json, je pourrais prendre une bibliothèque xml2json comme point de départ. Après tout, le langage HTML n’est qu’une variante du XML, n’est-ce pas?
PDATE: Ok, je devrais probablement donner un exemple. Ce que j'essaie de faire est le suivant. Analyser une chaîne de code HTML:
<div>
<span>text</span>Text2
</div>
dans un objet json comme ceci:
{
"type" : "div",
"content" : [
{
"type" : "span",
"content" : [
"Text2"
]
},
"Text2"
]
}
NOTE : Si vous n'avez pas remarqué le tag, je cherche une solution en Javascript
Je viens d'écrire cette fonction qui fait ce que vous voulez, essayez-la, dites-moi si cela ne fonctionne pas correctement pour vous:
// Test with an element.
var initElement = document.getElementsByTagName("html")[0];
var json = mapDOM(initElement, true);
console.log(json);
// Test with a string.
initElement = "<div><span>text</span>Text2</div>";
json = mapDOM(initElement, true);
console.log(json);
function mapDOM(element, json) {
var treeObject = {};
// If string convert to document Node
if (typeof element === "string") {
if (window.DOMParser) {
parser = new DOMParser();
docNode = parser.parseFromString(element,"text/xml");
} else { // Microsoft strikes again
docNode = new ActiveXObject("Microsoft.XMLDOM");
docNode.async = false;
docNode.loadXML(element);
}
element = docNode.firstChild;
}
//Recursively loop through DOM elements and assign properties to object
function treeHTML(element, object) {
object["type"] = element.nodeName;
var nodeList = element.childNodes;
if (nodeList != null) {
if (nodeList.length) {
object["content"] = [];
for (var i = 0; i < nodeList.length; i++) {
if (nodeList[i].nodeType == 3) {
object["content"].Push(nodeList[i].nodeValue);
} else {
object["content"].Push({});
treeHTML(nodeList[i], object["content"][object["content"].length -1]);
}
}
}
}
if (element.attributes != null) {
if (element.attributes.length) {
object["attributes"] = {};
for (var i = 0; i < element.attributes.length; i++) {
object["attributes"][element.attributes[i].nodeName] = element.attributes[i].nodeValue;
}
}
}
}
treeHTML(element, treeObject);
return (json) ? JSON.stringify(treeObject) : treeObject;
}
Exemple de travail: http://jsfiddle.net/JUSsf/ (Testé en chrome, je ne peux pas garantir la prise en charge complète du navigateur - vous devrez le tester).
Il crée un objet contenant l'arborescence de la page HTML dans le format que vous avez demandé, puis utilise JSON.stringify()
, inclus dans la plupart des navigateurs modernes (IE8 +, Firefox 3+ .etc); Si vous avez besoin de supporter des navigateurs plus anciens, vous pouvez inclure json2.js .
Cela peut prendre comme argument un DOM element
Ou un string
contenant un XHTML valide (je crois, je ne suis pas sûr que la DOMParser()
s'étouffe dans certaines situations, car est réglé sur "text/xml"
ou si cela ne permet tout simplement pas de gérer les erreurs. Malheureusement, "text/html"
est mal pris en charge par le navigateur).
Vous pouvez facilement changer l'étendue de cette fonction en transmettant une valeur différente sous la forme element
. Quelle que soit la valeur que vous transmettez, ce sera la racine de votre carte JSON.
Prendre plaisir
html2json & json2html sur GitHub , qui est basé sur le fichier htmlparser.js de John Resig, inclut quelques cas de test et a très bien fonctionné pour moi.
Représenter des documents HTML complexes sera difficile et compliqué, mais je voulais simplement partager quelques techniques pour montrer comment lancer ce type de programme. Cette réponse diffère en ce sens qu’elle utilise l’abstraction des données et la méthode toJSON
pour générer récursivement le résultat.
Au dessous de, html2json
est une fonction minuscule qui prend un nœud HTML en entrée et renvoie une chaîne JSON en tant que résultat. Portez une attention particulière à la façon dont le code est assez plat, mais il est toujours capable de construire une arborescence imbriquée profondément - tout possible avec une complexité pratiquement nulle
// data Elem = Elem Node
const Elem = e => ({
toJSON : () => ({
tagName:
e.tagName,
textContent:
e.textContent,
attributes:
Array.from(e.attributes, ({name, value}) => [name, value]),
children:
Array.from(e.children, Elem)
})
})
// html2json :: Node -> JSONString
const html2json = e =>
JSON.stringify(Elem(e), null, ' ')
console.log(html2json(document.querySelector('main')))
<main>
<h1 class="mainHeading">Some heading</h1>
<ul id="menu">
<li><a href="/a">a</a></li>
<li><a href="/b">b</a></li>
<li><a href="/c">c</a></li>
</ul>
<p>some text</p>
</main>
Dans l'exemple précédent, le textContent
est un peu égorgé. Pour remédier à cela, nous introduisons un autre constructeur de données, TextElem
. Nous devrons mapper sur le childNodes
(au lieu de children
) et choisir de renvoyer le type de données correct basé sur e.nodeType
_ Cela nous rapproche un peu plus de ce dont nous pourrions avoir besoin
// data Elem = Elem Node | TextElem Node
const TextElem = e => ({
toJSON: () => ({
type:
'TextElem',
textContent:
e.textContent
})
})
const Elem = e => ({
toJSON : () => ({
type:
'Elem',
tagName:
e.tagName,
attributes:
Array.from(e.attributes, ({name, value}) => [name, value]),
children:
Array.from(e.childNodes, fromNode)
})
})
// fromNode :: Node -> Elem
const fromNode = e => {
switch (e.nodeType) {
case 3: return TextElem(e)
default: return Elem(e)
}
}
// html2json :: Node -> JSONString
const html2json = e =>
JSON.stringify(Elem(e), null, ' ')
console.log(html2json(document.querySelector('main')))
<main>
<h1 class="mainHeading">Some heading</h1>
<ul id="menu">
<li><a href="/a">a</a></li>
<li><a href="/b">b</a></li>
<li><a href="/c">c</a></li>
</ul>
<p>some text</p>
</main>
Quoi qu'il en soit, ce n'est que deux itérations sur le problème. Bien sûr, vous devrez vous occuper des cas où ils se présentent, mais ce qui est bien avec cette approche, c'est que cela vous donne beaucoup de flexibilité pour coder le code HTML comme vous le souhaitez en JSON - et sans introduire trop de complexité
D'après mon expérience, vous pourriez continuer à itérer avec cette technique et obtenir de très bons résultats. Si cette réponse intéresse tout le monde et souhaite que je développe sur quoi que ce soit, faites-le moi savoir ^ _ ^
Connexes: Méthodes récursives utilisant JavaScript: construction de votre propre version de JSON.stringify
Celui-ci semble très bon JSON au HTML et HTML au JSON https://github.com/andrejewski/himalaya
J'ai reçu peu de liens lorsque je lisais sur le framework complet ExtJS qui s'appelle JSON.
http://www.thomasfrank.se/xml_to_json.html
http://camel.Apache.org/xmljson.html
convertisseur XML en ligne JSON: http://jsontoxml.utilities-online.info/
[~ # ~] mettre à jour [~ # ~] BTW, Pour obtenir le code JSON ajouté, HTML doit également contenir des balises de type et de contenu. comme ceci ou vous devez utiliser une transformation xslt pour ajouter ces éléments lors de la conversion JSON
<?xml version="1.0" encoding="UTF-8" ?>
<type>div</type>
<content>
<type>span</type>
<content>Text2</content>
</content>
<content>Text2</content>
Il existe un simple convertisseur HTML vers JSON . Vous pouvez copier et coller le code HTML et cliquer sur Convertir pour convertir le code HTML au format JSON.
Et il y a beaucoup de convertisseurs HTML en ligne vers JSON .