XMLビルダ

Collection & Copy - JavaScriptマークアップビルダ、存在しないメソッド
http://d.hatena.ne.jp/brazil/20050905/1125896604
を読んで、すこし話題がずれるんですが、JavaScriptXMLマークアップビルダ作るならこんな感じかなぁ

/**
  よくあるHTMLエスケープ
  */
String.prototype.unTag=function(){
  return this.replace(/\&/g,'&amp;').replace(/\</g,'&lt;').replace(/\>/g,'&gt;').replace(/\"/g,'&quot;');
}
/**
  文字列をタグに
  */
String.prototype.xml=function(attr){
  var xml= new Array('<');
  xml.push(this);
  var f=0;
  if( typeof(attr)=='object' ){
    for(var i in attr)
      xml.push( " "+i+"=\""+attr[i].toString().unTag()+"\"" );
    f=1;
  }
  if( f>=arguments.length ){
    xml.push("/>");
  }else{
    xml.push(">");
    while( f<arguments.length ) xml.push( arguments[f++] ) ;
    xml.push("</"+this+">");
  }
  return xml.join("");
}

これで、たとえば

document.write(
  "form".xml({action:"/action.cgi"},
             "h2".xml('パスワード'),
             "input".xml({type:"text", name:"name"}),
             "input".xml({type:"password", name:"pass"})
               ) );
↓
<form action="/action.cgi">
<h2>パスワード</h2>
<input type="text" name="name"/>
<input type="password" name="pass"/>
</form>

なんかそれっぽい。
今は文字列に変換してるけど、document.createElement で書き直すと

String.prototype.xml=function(attr){
  var xml = document.createElement(this);
  var f=0;
  if( attr && typeof(attr)=='object' && !(attr instanceof Node) ){
    for(var i in attr) xml.setAttribute( i,attr[i] );
    f=1;
  }
  while( f <arguments.length ){
    var n = arguments[f];
    f++;
    if( typeof(n)!='object' ) n = document.createTextNode(n);
    xml.appendChild(n);
  }
  return xml;
}

これで

document.body.appendChild(
  "form".xml({action:"/action.cgi"},
             "h2".xml('パスワード'),
             "input".xml({type:"text", name:"name"}),
             "input".xml({type:"password", name:"pass"})
               ) );

DOMが作成できる。


汎用化して

function make(atr){
  String.prototype.xml = make[atr];
}
make.dom=function(){
  var xml = document.createElement(this);
  :DOMエレメントを作る
}
make.htmlstr=function(){
  var xml= new Array('<');
  :HTML文字列を作る
}

こんなかんじにしておくと

make("dom");
document.body.appendChild(
  "form".xml({action:"/action.cgi"},
             "h2".xml('パスワード'),
             "input".xml({type:"text", name:"name"}),
             "input".xml({type:"password", name:"pass"})
               ) );

make("htmlstr");
document.write(
  "form".xml({action:"/action.cgi"},
             "h2".xml('パスワード'),
             "input".xml({type:"text", name:"name"}),
             "input".xml({type:"password", name:"pass"})
               ) );

と、切り替えたりとか。