Карта HTML в JSON
Я пытаюсь отобразить HTML в JSON с неповрежденной структурой. Есть ли какие-либо библиотеки, которые делают это, или мне нужно будет написать свой собственный? Я полагаю, что если там нет библиотек html2json, я мог бы начать с библиотеки xml2json. В конце концов, html-это только вариант xml в любом случае правильно?
обновление: хорошо, я, вероятно, должен привести пример. Что я пытаюсь сделать, это следующее. Разбор строки html:
<div>
<span>text</span>Text2
</div>
в объект json вот так:
{
"type" : "div",
"content" : [
{
"type" : "span",
"content" : [
"Text2"
]
},
"Text2"
]
}
Примечание: в случае, если вы не заметили тег, я ищу решение в Javascript
6 ответов:
Я просто написал эту функцию, которая делает то, что вы хотите, попробуйте, дайте мне знать, если она не работает правильно для вас:
// 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; }рабочий пример:http://jsfiddle.net/JUSsf/ (протестировано в chrome, я не могу гарантировать полную поддержку браузера - вам придется это проверить).
создается объект, который содержит древовидную структуру HTML-страницы в формате, который вы просили, а затем использует
JSON.stringify()который входит в большинство современных браузеров (IE8+, Firefox 3+ .и т. д.); Если вам нужно поддерживать старые браузеры, вы можете включить json2.js.это может занять либо
DOM elementилиstringсодержащий допустимый XHTML в качестве аргумента (я считаю, я не уверен, чтоDOMParser()будет задыхаться в определенных ситуациях, как это установлено в"text/xml"или же он просто не обеспечивает обработку ошибок. К сожалению"text/html"имеет плохую поддержку браузера).вы можете легко изменить диапазон этой функции, передав другое значение как
element. Любое значение, которое вы передадите, будет корнем вашей карты JSON.наслаждайтесь
html2json & json2html на GitHub, который построен на htmlparser Джона Ресига.js, включает в себя несколько тестовых случаев и отлично работал для меня.
представление сложных HTML-документов будет сложным и полным угловых случаев, но я просто хотел поделиться несколькими методами, чтобы показать, как запустить такую программу. Этот ответ отличается тем, что он использует абстракцию данных и
toJSONметод рекурсивного построения результатаниже
html2jsonэто крошечные функция, которая принимает HTML-узел в качестве входных данных и возвращает строку JSON в результате. Обратите особое внимание на то, как код вполне плоский, но он по – прежнему способен создавать глубоко вложенную древовидную структуру-все это возможно практически с нулевой сложностью// 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>в предыдущем примере,
textContentполучает немного забит. Чтобы исправить это, мы вводим другой конструктор данных,TextElem. Нам придется составить карту надchildNodes(вместоchildren) и выберите, чтобы вернуть правильный тип данных на основеe.nodeType– это делает нас немного ближе к тому, что мы могли бы нужно// 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>в любом случае, это всего лишь две итерации по проблеме. Конечно, вам придется обращаться к угловым случаям, когда они возникают, но что приятно в этом подходе, так это то, что он дает вам большую гибкость для кодирования HTML, как вы хотите в JSON – и не вводя слишком много сложности
по моему опыту, вы можете продолжать повторять эту технику и достигать действительно хороших результатов. Если это ответ интересен всем и хотел бы, чтобы я расширил что-нибудь, дайте мне знать ^_^
Я получил несколько ссылок когда-то назад при чтении на ExtJS полная структура сама по себе является JSON.
http://www.thomasfrank.se/xml_to_json.html
http://camel.apache.org/xmljson.html
онлайн XML в JSON конвертер:http://jsontoxml.utilities-online.info/
обновление Кстати, чтобы получить JSON, как добавлено в вопросе, HTML должен иметь теги type & content в нем тоже так или вам нужно чтобы использовать некоторые преобразования xslt для добавления этих элементов при выполнении преобразования JSON
<?xml version="1.0" encoding="UTF-8" ?> <type>div</type> <content> <type>span</type> <content>Text2</content> </content> <content>Text2</content>
Это выглядит довольно хорошо JSON для HTML и HTML для JSON https://github.com/andrejewski/himalaya
есть простой HTML в JSON конвертер. Вы можете скопировать и вставить HTML-код и нажать на преобразование для преобразования HTML в JSON.
а их очень много онлайн HTML в JSON конвертеры.
Comments