﻿<!--

//===========================================================================
// ::: XObject
//---------------------------------------------------------------------------
// XML Object Serialize/Deserialize
// 
//---------------------------------------------------------------------------
// work for IE6(win), FireFox(win/mac), Safari(mac) 
// Copyright(C)2005 DIGITAL DREAM, Inc.
//===========================================================================

	function XObject( xmldata ){
	    if( typeof(xmldata) == "string" ) {
    	    this.xmlDoc = null;
	        this.xmlData = xmldata;
	    } else {
	        this.xmlDoc = xmldata;
	        this.xmlData = xmldata.xml;
	    }
        this.iname = "";
	//	alert( "################################# xmlData" + xmldata );
	}

	XObject.prototype.NODE_TEXT = 3;
	XObject.prototype.NODE_ATTRIBUTE = 2;
	XObject.prototype.NODE_ELEMENT = 1;

	XObject.NODE_ELEMENT = 1;
	XObject.NODE_ATTRIBUTE = 2;
	XObject.NODE_TEXT = 3;


//===========================================================================
// ::: XObject.createXOBJ 

	createXObj = XObject.createXObj = function( xmldata ){
   	    var iobj = new XObject( xmldata );
	    iobj = iobj.deserialize();
	    iobj.iname = this.iname;
	    return iobj;
	}
	
	
	formatXObj = XObject.formatXObj = function( xmldata ){
		var xmldoc;		
		if( typeof( xmldata ) == "string" ){
			xmldoc = createXMLDoc( xmldata );
		}else{
			xmldoc = xmldata;
		}
		var node = xmldoc;
		formatNode( xmldoc, xmldoc );
		return xmldoc;
	}
		
	formatNode = XObject.formatNode = function( doc, node ){
		var names = new Array();

		for( var child = node.lastChild ; child != null ; child = child.previousSibling ){
			if( child.nodeType > XObject.NODE_ELEMENT )	continue;
//			alert( "node name = " + child.nodeName );
			if( typeof( names[child.nodeName] ) == "undefined" ){
				names[child.nodeName] = 1;
			}else{
				names[child.nodeName]++;
			}
		}
		
		for( var elm in names ){
			if( names[elm] <= 1 ){
				names[elm] = -1;
			}
		}

		for( var child = node.lastChild ; child != null ; child = child.previousSibling ){
			if( child.nodeType > XObject.NODE_ELEMENT )	continue;
			if( names[child.nodeName] != -1 ){
				child.setAttribute("index", --names[child.nodeName] );
			}
		   	if( child.hasChildNodes() ){
	    	    formatNode( doc, child );
		    }			
		}
	}			

    createXMLDoc = XObject.createXMLDoc = function( xmldata ){
        var doc = new ActiveXObject( "Microsoft.XMLDOM" );
        
        doc.async = false;
        doc.loadXML( xmldata );
//        return doc.firstChild;
		return doc;
    }
    

	

//===========================================================================
		
     	
	XObject.prototype.toString = function(){
		return this.xmlData;
	}
	
//---------------------------------------------------------------------------
// ::: deserialize
	
	XObject.prototype.deserialize = function(){
	    var doc = this.xmlDoc;
		if( doc == null ) {
    		doc = new ActiveXObject( "Microsoft.XMLDOM" );
    		doc.async = false;
    		doc.loadXML( this.xmlData );
    	}
    	if( doc.hasChildNodes() ) {
   		    this.iname = doc.firstChild.nodeName;
   		    this.deserializeNode( doc, doc, "." );
   		}
   		this.xmlDoc = null;
   		return this;
	}
	
	XObject.prototype.deserializeNode = function( doc, node, basekey ){
//		alert( "###########################"+ basekey + " : " + node );
	    if( node.attributes ) {
		    for( var i = 0; i < node.attributes.length; i++ ){
				var attr = node.attributes.item( i );
		        var attrkey;
		        if( basekey.length == 1 && basekey.charAt(0) == "." ){
    		    	attrkey = basekey + "#" + attr.name;
    		    } else {
    		    	attrkey = basekey + ".#" + attr.name;
    		    }
			    this[attrkey] = attr.value;
//			    alert( attrkey + ": " + this[attrkey] );
	    	}
	    }
		
		if( node.lastChild == null ){
		    this[basekey] = "";
		}
		
		for( var child = node.lastChild ; child != null ; child = child.previousSibling ){
			if( child.nodeType > this.NODE_TEXT )	continue;
		
    		var childkey = basekey + ( basekey == "." ? "" : "." ) + child.nodeName;

//			alert( "C = " + childkey + " node type = " + child.nodeType );

   			if( child.attributes && child.getAttribute("index") ){
    			// 配列の初期化
	    		if( !(this[childkey] instanceof Array) ){
		    		this[childkey] = [];
			    }
			    
   				// 子ノードにindex属性があれば this[".node.child"][index] に保存する
    			var index = this.getNum(child.getAttribute("index"));
	    		if( index >= 0 ){
			    	this[childkey][index] = createXObj(child);
//			    	alert( this[childkey][index].dump() );
   					//trace("alert", "[INDEX] " + childkey + "[" + index + "]: " + this[childkey][index]);
    			}
	    		
		    } else if( child.attributes && child.getAttribute("key") ){
			    // 配列の初期化
   				if( !(this[childkey] instanceof Array) ){
    				this[childkey] = [];
	    		}
		    	
			    // 子ノードにkey属性があれば this[".node.child"][key] に保存する
   				var k = child.getAttribute("key");
    			if( k != "" ){
	    			this[childkey][k] = createXObj(child);
		    		//trace("alert", "[KEY] " + childkey + "[" + k + "]: " + this[childkey][k]);
			    }
			    
   			} else if( child.attributes && child.getAttribute("iname") ){
   				// 子ノードにiname属性があれば this[".node.child(iname)"] に保存する
    			var ins = child.getAttribute("iname");
		    	this[childkey+"("+ins+")"] = createXObj(child);
			    //trace("alert", "[INAME] " + inskey + ": " + this[inskey]);
			}else if( child.attributes && child.getAttribute("xobj") ){
				this[childkey] = createXObj(child);
			    
		    } else if( child.nodeType == this.NODE_TEXT ){
	        	// 子ノードの値を this[".node"] に保存する
		    	this[basekey] = child.nodeValue;
		   	    //trace("alert", "[TEXT] " + doc.nodeName + " // " + basekey + " / " + childkey + ": " + this[childkey]);
				       
        	} else {
	        	// 再帰的に子ノードを処理する
//				alert( "[TOCHILD] " + childkey );
		   	    if( child.hasChildNodes() ){
	    	    	this.deserializeNode( doc, child, childkey );
		        }
		    }
		}
//		alert ( "@ "+ basekey + " : " + node.xml );

    }

//---------------------------------------------------------------------------
// ::: serialize

    XObject.prototype.serialize = function () {
        //DOMの作成
  		doc = new ActiveXObject( "Microsoft.XMLDOM" );
   		doc.async = false;
   		
   		//ルートノードの作成
   		var rootnode = doc.createElement( this.iname );
   		doc.appendChild( rootnode );
   		for( var item in this ){
   		    // "." で始まる項目以外を読み飛ばす
   		    if( item.charAt(0) != '.' ){
   		        continue;
   		    }
   		    
   		    //各ノードの名前を取得
   		    var elemsOrg = item.split(".");
   		    var elems = item.split(".");
   		    var lastelem = elems.pop();
   		    elems.shift();
   		    var parent_elems = elems;
   		    
   		    //親ノードを作成
   		    var lastnode;
   		    if( elemsOrg.length == 2 ){
   		        lastnode = this.generate_xml_nodetree( doc, elems );
   		    } else {
   		        if( lastelem.indexOf("#") > 0 ) {
   		            elemsOrg[elemsOrg.length-1] = lastelem.slice(0, lastelem.indexOf("#"));
   		            lastelem = lastelem.slice(lastelem.indexOf("#"));
   		        }
   		        lastnode = this.generate_xml_nodetree( doc, elemsOrg );
   		    }
   		    
   		    //trace("alert", "LASTELEM: " + lastelem );
   		    //trace("alert", "LASTNODE: " + lastnode.xml );
   		    
   		    //子ノードを作成
   		    if( this[item] instanceof Array ){
   		        //配列から、index属性やkey属性のXMLを作る
   		        for( var index in this[item] ){
   		            lastnode.appendChild( createXMLDoc(this[item][index]).firstChild );
   		            //trace("alert", "SET INDEX[" + index + "]: " + this[item][index]);
   		        }
   		    } else if (lastelem.charAt(0) == "#" ){
   		        // .#attr 属性データをXMLに追加する
   		        var attr = lastelem.substr(1);
   		        //trace("alert", "SET ATTR: " + attr + ": " + this[item] );
   		        lastnode.setAttribute( attr, this[item] );
   		        
   		    } else if ( lastelem.charAt(lastelem.length-1) == ')' ) {
   		        // .child(iname) iname属性のXMLを作る
   		        var found = lastelem.indexOf('(');
   		        var taginame = lastelem.substring( found + 1, lastelem.length - 1 );
   		        var tagelem = lastelem.substring( 0, found );
   		        lastnode.appendChild( createXMLDoc(this[item]).firstChild );
   		        //trace("alert", "SET INAME: " + lastelem + ": " + this[item]);
   		        
   		    } else {
   		        //テキストノードを追加
   		        //trace("alert", "SET TEXT: " + lastelem + ": " + this[item]);
   		        lastnode.appendChild( doc.createTextNode(this[item]) );
   		    }
   		}
   		return doc.firstChild.firstChild.xml;
    }
    
    XObject.prototype.generate_xml_nodetree = function( doc, elems ){
        var node = doc.firstChild;
        for( var i = 0 ; i < elems.length-1 ; i++ ){
            //子ノードを探す
            if( elems[i] == "" || elems[i].charAt(0) == "#" ) {
                continue;
            }
            for( var child = node.firstChild ; child != null ; child = child.nextSibling ) {
                if( child.nodeName == elems[i] ){
                    break;
                }
            }
            if( child == null ){
                var child = doc.createElement( elems[i] );
                node.appendChild( child );
                //trace("alert", "GEN: " + child.xml );
            }
            node = child;
        }
        return node;
    }
    
    XObject.prototype.getNum = function( data ) {
	   	if( isNaN(data) ){
	    	return -1;
	    }
		return data;
	}
	

	XObject.LF = "<br/>";

	XObject.prototype.dump = function( objname ){
		XObject.dump( this, objname );
	}


	XObject.dump = function( obj, objname ) {
		if( typeof( objname ) == 'undefined' ){ objname = "xobjs"; }

		var buf = "";
    		
		for( var index in obj ){
			var name = objname + '["' + index + '"]';
			var itype = typeof( obj[index] );
			if( itype == 'function' ) continue;
//			alert( "obj[" + index + "] ( " + itype + ") = " + obj[index] );
			if( itype == 'object' ){
				buf += ( XObject.dump( obj[index], name ) + XObject.LF );
			}else {
				buf += ( name + " = " + obj[index] + XObject.LF );
			}
		}
		return buf;
	}




-->