node4x

XML/XMLListNode を愚直に。

function node4x(xml, doc){
  doc = doc || document;
  if(xml.length() === 1) switch(xml.nodeKind()){
    case 'attribute': let at = true;
    case 'element':
    let {uri, localName: name} = xml.name();
    if(at){
      at = uri ? doc.createAttributeNS(uri, name) : doc.createAttribute(name);
      at.nodeValue = xml;
      return at;
    }
    let lm = uri ? doc.createElementNS(uri, name) : doc.createElement(name);
    for each(let a in xml.@*::*){
      let {uri, localName: name} = a.name();
      uri ? lm.setAttributeNS(uri, name, a) : lm.setAttribute(name, a);
    }
    lm.appendChild(node4x(xml.*::*, doc));
    return lm;
    case 'text': return doc.createTextNode(xml);
    case 'comment': return doc.createComment(xml.toString().slice(4, -3));
    case 'processing-instruction':
    let [, target, data] = /^<\?(\S+) ?([^]*)\?>$/(xml);
    return doc.createProcessingInstruction(target, data);
  }
  if(0 in xml && xml[0].nodeKind() === 'attribute')
    return [node4x(x, doc) for each(x in xml)];
  var df = doc.createDocumentFragment();
  for each(let x in xml) df.appendChild(node4x(x, doc));
  return df;
}
    • ignoreWhitespace/prettyPrinting/prettyIndent の影響を受けない。
    • 属性値も生成可能。
node4x(<_ name="value"/>.@*) //=> [object Attr]
node4x(<_ n="v" m="x" />.@*) //=> [object Attr],[object Attr]
  • ×
    • たぶん遅い。
    • 属性値の用途皆無。
はまりどころ

comment/processing-instuction は初期状態で無視される。
E4X traps に追記した。