asp에는 JSON의 서버쪽 모듈이 없다.
그 이유든 아니든 XML로 데이터 통신을 할일이 늘고 있고, 모두들 나름대로 XML를 컨트롤 하는 함수를 만들어서 쓰고 있다.
ASP쪽에선 나름대로 노하우를 쌓아가고 있지만,
Ajax에서는 XMLHttpRequest 로 XMLDOM를 반한받은후 컨트롤 하기가 여간 버겨운것이 아니였다.
(javascript가 익숙하지 않은것이 가장큰 이유겠지만. )
서버단에서 부터 JSON으로 보낼 수 있다면, 더 좋겠지만, ASP에서는 아직 그런 모듈이 없기때문에,
통신은 XML로 하고 반환받은 XML DOM를 JSON으로 변환만 할 수 있어도 Ajax개발을 할때 많은 도움이 될것 같다.
그래서 현재 프래임워크로 선택한 Prototype.js기반으로 작동하는 JSONParser가 필요했고,
Yusuke Kawasaki 가 제작한 jkl-parsexml.js를 참고하여 Prototype.js기반의 JSONParser Object를 추가했다.  (말이 참고지... 따왔다. ㅡ ㅡ;;)

사용법은 다음과 같다.

var AFUrl = "./test.xml"
var AvatarFD ;
//ajax XML 로드
function loadAjaxXML(url, pars, fncSuccess, fncFailure){
var myAjax = new Ajax.Request(
    url,
    {
      method: 'get',
      parameters: pars,
      onSuccess: fncSuccess,
      onFailure: fncFailure
    });
}
function setAvatarFoundation(originalRequest){
AvatarFD = new JSONParser(originalRequest);
var json = AvatarFD.data;
alert("json.Avatar.Foundation.IMGPath=" + json.Avatar.Foundation.FullItem.ItemName)
 }
function falseLoad(){alert('XML Load Error');}
loadAjaxXML(AFUrl, '', setAvatarFoundation, falseLoad)

객체 JSONParser에 할당된 originalRequest는 Prototype.js에서 Ajax.Request를 사용할때 반환되는 원본 Oject다. 이걸 인자로 하여 객체를 만들고, 메소드 data()를 써주면, XML은 JSON으로 파싱된되고,샘플의  json.Avatar.Foundation.FullItem.ItemName처럼 XML이 노드명을 Object Name으로 하여 하위접근이 가능해진다.


다음은 Prototype.js에 추가된 소스다. 부족한 샘플과 추가 설명은 다음에...

//==============================================================================
JSONParser = Class.create();
Object.extend(JSONParser.prototype, {
  //initialize
initialize: function(req) {
 this.req = req;
 if ( ! this.req ) return;
 if ( this.req.responseXML ) {
  this.root =  this.req.responseXML.documentElement;    // XMLHTTPRequest
 } else {
 
  this.root =  this.req.documentElement;                // IXMLDOMDocument
 }
 this.data = this.parseDocument(this.root);
},
parseDocument: function(root){
 
 var ret = this.parseElement(root);
 var json = {};
 json[root.nodeName] = ret;                      // root nodeName
 
 return json;

}
 
});

// ================================================================
//  convert from DOM Element to JavaScript Object
//  method: parseElement( element )
JSONParser.prototype.parseElement = function(elem){

   //  COMMENT_NODE

   if ( elem.nodeType == 7 ) {
       return;
   }
   //  TEXT_NODE CDATA_SECTION_NODE
   if ( elem.nodeType == 3 || elem.nodeType == 4 ) {
       var bool = elem.nodeValue.match( /[^\x00-\x20]/ ); // for Safari
       if ( bool == null ) return;     // ignore white spaces
       return elem.nodeValue;
   }
   var retval;
   var cnt = {};
   //  parse attributes

   if ( elem.attributes && elem.attributes.length ) {
       retval = {};
       for ( var i=0; i<elem.attributes.length; i++ ) {
           var key = elem.attributes[i].nodeName;
           if ( typeof(key) != "string" ) continue;
           var val = elem.attributes[i].nodeValue;
           if ( ! val ) continue;
           if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0;
           cnt[key] ++;
           this.addNode( retval, key, cnt[key], val );
       }
   }
   //  parse child nodes (recursive)
   if ( elem.childNodes && elem.childNodes.length ) {
 
       var textonly = true;
       if ( retval ) textonly = false;        
       for ( var i=0; i<elem.childNodes.length && textonly; i++ ) {
           var ntype = elem.childNodes[i].nodeType;
           if ( ntype == 3 || ntype == 4 ) continue;
           textonly = false;
       }
       if ( textonly ) {
           if ( ! retval ) retval = "";
           for ( var i=0; i<elem.childNodes.length; i++ ) {
               retval += elem.childNodes[i].nodeValue;
           }
       } else {
           if ( ! retval ) retval = {};
           for ( var i=0; i<elem.childNodes.length; i++ ) {
               var key = elem.childNodes[i].nodeName;
               if ( typeof(key) != "string" ){ continue;}
               var val = this.parseElement( elem.childNodes[i] );
               if ( ! val ){ continue;}
               if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0;
               cnt[key] ++;
   
               this.addNode( retval, key, cnt[key], val );
           }
       }
   }
   return retval;
}
// ================================================================
//  method: addNode( hash, key, count, value )
JSONParser.prototype.addNode = function ( hash, key, cnts, val ) {
if ( cnts == 1 ) {                      // 1st sibling
 hash[key] = val;
} else if ( cnts == 2 ) {               // 2nd sibling
 hash[key] = [ hash[key], val ];
} else {                                // 3rd sibling and more
 hash[key][hash[key].length] = val;
}
};
JSONParser.nodeType = [
   "",
   "ELEMENT_NODE",                 // 1
   "ATTRIBUTE_NODE",               // 2
   "TEXT_NODE",                    // 3
   "CDATA_SECTION_NODE",           // 4
   "ENTITY_REFERENCE_NODE",        // 5
   "ENTITY_NODE",                  // 6
   "PROCESSING_INSTRUCTION_NODE",  // 7
   "COMMENT_NODE",                 // 8
   "DOCUMENT_NODE",                // 9
   "DOCUMENT_TYPE_NODE",           // 10
   "DOCUMENT_FRAGMENT_NODE",       // 11
   "NOTATION_NODE"                 // 12
];
2006/05/11 21:13 2006/05/11 21:13
Trackback address :: http://zziuni.pe.kr/zziuni/trackback/222

Comments List

Write a comment.

[로그인][오픈아이디란?]