반응형

JavaScript에서 xml문서를 파싱하는 방법



DOM파서 이용

DOM파서는 xml파일을 읽을때 문자열로 읽어져서 그 문자열을 xml객체로 만들어줄 때 사용한다.

var parser = new DOMParser();

xmlDoc = parser.parseFromString(text,"text/xml"); //text에 xml파일에서 읽은 문자열들이 들어있다.


XML객체에서 데이터를 얻는 방법

xmlObject.documentElement;    //xml 객체에서 문서 요소를 얻는다.

xmlObject.documentElement.childNodes // 얻은 문서 요소 내 하위 노드들을 가진다.


위 방법처럼 계속 하위노드들을 파고들어 필요한 내용을 얻을 수 있다.


다른 방법으로는 xml문서를 object나 json 객체로 바꿔서 xml 객체 내 정보들을 이용할 수 있다.


네이버에서 제공해주는 xml문자열 파싱 함수

네이버에서 제공해주는 xml문자열을 Object로 바꿔주는 함수이다. 파라미터로 xml형식으로 된 문자열을 넣어주면 된다.

이 함수는  CDATA로 value가 선언된 xml 형식 문자열에서 사용해야한다.

알아보니 한국 웹 사이트에서 사용되는 xml문서들은 CDATA형식이지만 외국 사이트에서 제공해주는 xml 문서는 제대로 작동 안될 수 도 있다.


    var JINDO = new Object();

    JINDO.xml2obj = function(xml) 

    { 

        var obj = {}, que = [], depth = 0;


        // attribute를 해석하기 위한 함수        

        var parse_attr = function(oobj, str) {

                str.replace(/([^=\s]+)\s*=\s*"([^"]*)"/g, function(a0,a1,a2) {

                        oobj[a1] = a2;

                });

        }

        

        // 주석, XML선언, 태그 사이 공백 등의 의미 없는 코드를 삭제

        xml = xml.replace(/<(\?|\!-)[^>]*>/g,'').replace(/>\s+</g, '><');

        

        // 하위 노드가 없는 태그는 하나의 닫힌 태그로 수정

        xml = xml.replace(/<([^!][^ >]+)(\s[^>]*)?><\/\1>/g, '<$1$2 />').replace(/^\s+|\s+$/g, '');


        // 함수 객체를 정규 표현식 처리의 인자로 줘서 iterator로 사용

        xml = xml.replace(/<\/?([^\!][^ >]*)(\s[^>]*)?>(<\/$1>|<\!\[CDATA\[(?:(.|\s)*?)\]\]>|[^<>]*)/g, function(a0,a1,a2,a3)

        {

                // IE에서 일치하는 내용이 없으면 undefined로 전달되므로

                // 빈 문자열로 변경해 다른 브라우저와의 호환성을 맞춤

                if (typeof a1 == 'undefined') a1 = '';

                if (typeof a2 == 'undefined') a2 = '';

                if (typeof a3 == 'undefined') a3 = '';

                

                if (a0.substr(1,1) == '/') { // 현재 태그가 닫는 태그라면,

                        // 깊이를 1만큼 감소 

                        depth--;

                } else if (que.length == 0) { // 객체 큐에 객체가 없다면,

                        que[depth] = obj; // 초기의 객체를 큐에 넣고

                        parse_attr(obj, a2); // attribute를 해석

                } else {

                        var k  = a1, o = {}, is_closed = false;

                        

                        is_closed = (a2.substr(-1,1) == '/');

                        if (a3.length > 0 || is_closed) { // 텍스트 노드가 있다면

                                o = a3; // 추가할 객체는 문자열 객체

                                

                                // CDATA라면 전달받은 그대로 리턴하고

                                // 그렇지 않다면 decode 해서 리턴

                                if (o.substr(0,9) == '<![CDATA[' && o.substr(-3,3) == ']]>') o = o.substring(9, o.length-3);

                                else o = o.replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&');

                        }

                        

                        // 객체를 할당하기 전에 태그 이름이 이미 존재하는지 살펴보고

                        // 이전에 존재하는 태그라면, 배열로 만든다. 이미 배열이라면 현재의 객체를 배열에 추가

                        if (typeof que[depth][k] == 'undefined') {

                                que[depth][k] = o;

                        } else {                                

                                var v = que[depth][k];

                                if (que[depth][k].constructor != Array) que[depth][k] = [v];

                                que[depth][k].push(o);

                        }


                        // attribute를 해석

                        parse_attr(o, a2);

                        

                        if (!is_closed) que[++depth] = o;       

                }

                

                return '';

        });

        return obj;

    }


---------------------------------------------------------------------------------------------------------------

구글에서 검색해서 찾은 xml 객체를 JSON으로 바꿔주는 함수

이 함수는 xml 문서를 Json객체로 바꿔주는 함수이다.


function xmlToJson(xml) 

{    

    // Create the return object

    var obj = {};


    if (xml.nodeType == 1) { // element

        // do attributes

        if (xml.attributes.length > 0) {

        obj["@attributes"] = {};

            for (var j = 0; j < xml.attributes.length; j++) {

                var attribute = xml.attributes.item(j);

                obj["@attributes"][attribute.nodeName] = attribute.nodeValue;

            }

        }

    } else if (xml.nodeType == 3) { // text

        obj = xml.nodeValue;

    }


    // do children

    if (xml.hasChildNodes()) {

        for(var i = 0; i < xml.childNodes.length; i++) {

            var item = xml.childNodes.item(i);

            var nodeName = item.nodeName;

            if (typeof(obj[nodeName]) == "undefined") {

                obj[nodeName] = xmlToJson(item);

            } else {

                if (typeof(obj[nodeName].push) == "undefined") {

                    var old = obj[nodeName];

                    obj[nodeName] = [];

                    obj[nodeName].push(old);

                }

                obj[nodeName].push(xmlToJson(item));

            }

        }

    }

    return obj;

};


반응형

'웹 프로그래밍 > JavaScript' 카테고리의 다른 글

window.onload vs $(document).ready() vs $(window).load()  (0) 2018.10.16
JavaScript xml 사용  (0) 2016.01.27
JavaScript 함수 선언  (0) 2016.01.04

+ Recent posts