IT story

HTML을 JSON에 매핑

hot-time 2020. 12. 25. 09:29
반응형

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로 솔루션을 찾고 있습니다.


방금 원하는 기능을 수행하는이 함수를 작성했습니다. 제대로 작동하지 않는 경우 알려주세요.

// 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+ .etc)에 포함 된 사용합니다. 이전 브라우저를 지원해야하는 경우 json2.js 를 포함 할 수 있습니다 .

인수로 유효한 XHTML을 포함 DOM element하거나 string포함 할 수 있습니다. (저는 이것이 DOMParser()설정되어있는 특정 상황에서 질식 할 "text/xml"것인지 아니면 오류 처리를 제공하지 않는 것인지 확실 하지 않습니다. 불행히도 "text/html"브라우저 지원이 좋지 않습니다. ).

다른 값을로 전달하여이 함수의 범위를 쉽게 변경할 수 있습니다 element. 전달하는 값이 무엇이든 JSON 맵의 루트가됩니다.

즐겨


John Resig의 htmlparser.js를 기반으로 구축 된 GitHub의 html2json & json2html 에는 몇 가지 테스트 케이스가 포함되어 있으며 저에게 잘 맞았습니다.


복잡한 HTML 문서를 표현하는 것은 어렵고 코너 케이스로 가득 차있을 것입니다. 그러나 저는 이러한 종류의 프로그램을 시작하는 방법을 보여주기 위해 몇 가지 기술을 공유하고 싶었습니다. 이 답변은 데이터 추상화와 toJSON결과를 재귀 적으로 빌드하는 방법을 사용한다는 점에서 다릅니다.

아래 는 HTML 노드를 입력으로 받고 결과로 JSON 문자열을 반환 html2json하는 작은 함수입니다. 코드가 얼마나 평평하지만 여전히 깊이 중첩 된 트리 구조를 구축 할 수 있는지 특히주의하십시오. 거의 모든 복잡성이 거의없이 가능합니다.

// 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>

Anyway, that's just two iterations on the problem. Of course you'll have to address corner cases where they come up, but what's nice about this approach is that it gives you a lot of flexibility to encode the HTML however you wish in JSON – and without introducing too much complexity

In my experience, you could keep iterating with this technique and achieve really good results. If this answer is interesting to anyone and would like me to expand upon anything, let me know ^_^

Related: Recursive methods using JavaScript: building your own version of JSON.stringify


This one looks pretty good JSON to HTML and HTML to JSON https://github.com/andrejewski/himalaya


I got few links sometime back while reading on ExtJS full framework in itself is JSON.

http://www.thomasfrank.se/xml_to_json.html

http://camel.apache.org/xmljson.html

online XML to JSON converter : http://jsontoxml.utilities-online.info/

UPDATE BTW, To get JSON as added in question, HTML need to have type & content tags in it too like this or you need to use some xslt transformation to add these elements while doing JSON conversion

<?xml version="1.0" encoding="UTF-8" ?>
<type>div</type>
<content>
    <type>span</type>
    <content>Text2</content>
</content>
<content>Text2</content>

There is a simple HTML to JSON converter. You can copy and paste the HTML code and click on Convert to convert the HTML to JSON.

And there are a lot of Online HTML to JSON Converters.

ReferenceURL : https://stackoverflow.com/questions/12980648/map-html-to-json

반응형