Карта 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

504   6  

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 – и не вводя слишком много сложности

по моему опыту, вы можете продолжать повторять эту технику и достигать действительно хороших результатов. Если это ответ интересен всем и хотел бы, чтобы я расширил что-нибудь, дайте мне знать ^_^

по теме: рекурсивные методы с использованием JavaScript: создание собственной версии 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

    Ничего не найдено.