3

I have an XHTML document. I use XHR to import another XML document that is supposed to be XHTML, except the author forgot to put an xmlns on the root. As such, all nodes in the XML document have no namespace.

When I import a node from this other document and append it to my document I get a node that looks right (e.g. <h1>Hi Mom!</h1>) but that has no namespace. As such, the web browser applies display:inline.

I could fix this by using code like the following (untested)…but I'd rather not, if a better route exists:

function changeNodeNamespace(node,namespace){
  var dup = document.createElementNS(namespace,node.nodeName);
  if (node.hasAttributes()){
    for (var a=node.attributes,i=a.length;i--;){
      dup.setAttributeNS(a[i].namespaceURI,a[i].nodeName,a[i].value);
    }
  }
  if (node.hasChildNodes()){
    for (var a=node.childNodes,i=0,len=a.length;i<len;++i){
      if (a[i].nodeType==1){ // ELEMENT_NODE
        dup.appendChild(changeNodeNamespace(a[i],namespace));
      }else{
        dup.appendChild(a[i].cloneNode(false));
      }
    }
  }
  return dup;
}

Other than re-authoring the documents I import to have the correct namespace, or-recursively re-creating every element/attribute/textnode in a new namespace based on the originals, can I import the elements themselves and somehow change their namespace to http://www.w3.org/1999/xhtml?

Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • Can you change the default namespace to XHTML and use a namespace for everything else? There is also [createElementNS](http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-DocCrElNS) for creating elements in a particular namespace. – RobG Mar 22 '12 at 23:12
  • @RobG The host document does have a default XHTML namespace. The loaded document does not, and that's the problem. If I edit that document to have a default XHTML namespace (thus applying the namespace to all descendants) everything works fine. The question is: _if I load an XML document that has node in the 'wrong' namespace, is there a way to transfer them without using a recursive `createElementNS` and `setAttribute` and `createTextNode` etc. to generate similar nodes in another namespace?_ – Phrogz Mar 22 '12 at 23:18

1 Answers1

1

XSLT can do the trick, and a library such as Sarissa or AJAXSLT can help simplify the JavaScript syntax.

Community
  • 1
  • 1
Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
  • What an interesting suggestion! Use XSLT to transform the element into a new one. Tricky; not quite what I was looking for, you but you certainly get a +1 for the AJAXSLT reference (real XPath in JS? Joy!). – Phrogz May 16 '12 at 20:45