MMeijer
asked on
[MSXML] Copying XHTML node to the document
After loading the xml document, i try to clone a node from that document to a variable in the script to later on append it to the window.document. The node in question is a xhtml element type node.
It works perfect (..well as expected :| ) in Mozilla, but in IE i get the error:"No such interface suported."
Wich references to line where i try to append it as a child of another element in the window.document tree;
Anyone familiar with this problem?
It works perfect (..well as expected :| ) in Mozilla, but in IE i get the error:"No such interface suported."
Wich references to line where i try to append it as a child of another element in the window.document tree;
Anyone familiar with this problem?
send code, please
ASKER
test.htm file:
8><----------------------- ---------- ---------- --------
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>EE</title>
</head>
<body >
<script type="text/javascript">
function ElementControl()
{
this.element = document.createElement("di v");
this.fromXmlFile = function(sXml)
{
var blnMs = (navigator.appName.toLower Case().ind exOf("micr osoft")!=- 1);
var blnLoaded = false;
var objXmlDoc = null;
if(blnMs)
objXmlDoc = new ActiveXObject("microsoft.x mldom");
else
objXmlDoc = document.implementation.cr eateDocume nt("", "", null);
objXmlDoc.async = false;
blnLoaded = objXmlDoc.load(sXml)
if(!blnLoaded)
{
var strErrMessage = "Failed to load XML";
if(objXmlDoc.parseError)
strErrMessage += ", reason: " + objXmlDoc.parseError.reaso n;
return this.onerror(strErrMessage );
}
void this.fromXmlDomNode(objXml Doc.docume ntElement) ;
}
this.fromXmlDomNode = function(oNode)
{
if(oNode==undefined || oNode==null || oNode.nodeName!="div")
return;
this.element = oNode.cloneNode(true);
}
this.render = function(oParent)
{
objParent = oParent? oParent: document.body;
void objParent.appendChild(this .element);
}
this.onerror = function(){return;}
}
var objControl = new ElementControl()
objControl.onerror = function(e)
{
alert(e);
}
window.onload = function()
{
void objControl.fromXmlFile("te st.xml");
objControl.render();
}
</script>
</body>
</html>
-------------------------- ---------- ---------- -----><8
test.xml file:
8><----------------------- ---------- ---------- --------
<?xml version="1.0" encoding="utf-8"?>
<div xmlns="http://www.w3.org/1999/xhtml">Hello world!</div>
-------------------------- ---------- ---------- -----><8
in mozilla this will write "Hello world!", in IE the error happense
8><-----------------------
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>EE</title>
</head>
<body >
<script type="text/javascript">
function ElementControl()
{
this.element = document.createElement("di
this.fromXmlFile = function(sXml)
{
var blnMs = (navigator.appName.toLower
var blnLoaded = false;
var objXmlDoc = null;
if(blnMs)
objXmlDoc = new ActiveXObject("microsoft.x
else
objXmlDoc = document.implementation.cr
objXmlDoc.async = false;
blnLoaded = objXmlDoc.load(sXml)
if(!blnLoaded)
{
var strErrMessage = "Failed to load XML";
if(objXmlDoc.parseError)
strErrMessage += ", reason: " + objXmlDoc.parseError.reaso
return this.onerror(strErrMessage
}
void this.fromXmlDomNode(objXml
}
this.fromXmlDomNode = function(oNode)
{
if(oNode==undefined || oNode==null || oNode.nodeName!="div")
return;
this.element = oNode.cloneNode(true);
}
this.render = function(oParent)
{
objParent = oParent? oParent: document.body;
void objParent.appendChild(this
}
this.onerror = function(){return;}
}
var objControl = new ElementControl()
objControl.onerror = function(e)
{
alert(e);
}
window.onload = function()
{
void objControl.fromXmlFile("te
objControl.render();
}
</script>
</body>
</html>
--------------------------
test.xml file:
8><-----------------------
<?xml version="1.0" encoding="utf-8"?>
<div xmlns="http://www.w3.org/1999/xhtml">Hello world!</div>
--------------------------
in mozilla this will write "Hello world!", in IE the error happense
The tree model is slightly different in both browsers, so we need the code to help you speciffic.
You have to extend the render() method:
this.render = function(oParent){
objParent = (oParent)? oParent: document.body;
newNode = document.createElement(thi s.element. nodeName);
txtNode = document.createTextNode(th is.element .text);
newNode.appendChild(txtNod e);
objParent.appendChild(newN ode);
}
The only reason I can imagine for this is that the IE enforces that child nodes belong to same parent document.
Therefore you have to recreate the child node:
http://www.zvon.org/xxl/DOM2reference/DOM2/Output/data/interfaces/Node.html#appendChild
this.render = function(oParent){
objParent = (oParent)? oParent: document.body;
newNode = document.createElement(thi
txtNode = document.createTextNode(th
newNode.appendChild(txtNod
objParent.appendChild(newN
}
The only reason I can imagine for this is that the IE enforces that child nodes belong to same parent document.
Therefore you have to recreate the child node:
http://www.zvon.org/xxl/DOM2reference/DOM2/Output/data/interfaces/Node.html#appendChild
what about attributes? This way you'd lost'em
NS + IE way (til this moment we got only NS/Mozilla way and only IE way):
this.render = function(oParent)
{
objParent = (oParent)? oParent: document.body;
newNode = document.createElement(thi s.element. nodeName);
newNode.innerHTML = (navigator.appName == 'Netscape')?this.element.i nnerHTML:t his.elemen t.text;
objParent.appendChild(newN ode);
}
can't make it work in Opera
this.render = function(oParent)
{
objParent = (oParent)? oParent: document.body;
newNode = document.createElement(thi
newNode.innerHTML = (navigator.appName == 'Netscape')?this.element.i
objParent.appendChild(newN
}
can't make it work in Opera
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
And the last is tested in IE6.0 and Mozilla1.5
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Maybe you two can (Zvonko, alambres) can extract something useful from:
http://www.howtocreate.co.uk/tutorials/jsexamples/importingXML.html
Though, it does look at first glance that copying over attributes would probably be a manual exercise.
http://www.howtocreate.co.uk/tutorials/jsexamples/importingXML.html
Though, it does look at first glance that copying over attributes would probably be a manual exercise.
Generally does this question belong into XML topic area:
https://www.experts-exchange.com/Web/Web_Languages/XML/
https://www.experts-exchange.com/Web/Web_Languages/XML/
ASKER
microsoft domdocument cannot exchange nodes with window.document, atleast not with a simple cloneNode or reference.
Mozilla's domdocument can, but need's a namespaceURI
I've solved this with a function (attached to the ElementControl object):
-------------------------- -
this.importNode = function(oNode)
{
if(oNode==undefined || oNode==null)
return null;
var objNodeResult = null;
if(oNode.nodeType == 1)
{
objNodeResult = document.createElement(oNo de.nodeNam e);
for(var i=0; i<oNode.attributes.length; i++)
void objNodeResult.setAttribute (oNode.att ributes[i] .name, oNode.attributes[i].value)
for(var i=0; i<oNode.childNodes.length; i++)
void objNodeResult.appendChild( this.impor tNode(oNod e.childNod es[i]));
}
if(oNode.nodeType == 3)
{
objNodeResult = document.createTextNode(oN ode.nodeVa lue);
}
return objNodeResult;
}
-------------------------- -
this function chages to
-------------------------- -
this.fromXmlDomNode = function(oNode)
{
if(oNode==undefined || oNode==null || oNode.nodeName!="div")
return;
this.element = this.importNode(oNode)
}
-------------------------- -
now i can write partial HTML document in the xml file, but another problem shows the style attribute doesnt work with IE
Mozilla's domdocument can, but need's a namespaceURI
I've solved this with a function (attached to the ElementControl object):
--------------------------
this.importNode = function(oNode)
{
if(oNode==undefined || oNode==null)
return null;
var objNodeResult = null;
if(oNode.nodeType == 1)
{
objNodeResult = document.createElement(oNo
for(var i=0; i<oNode.attributes.length;
void objNodeResult.setAttribute
for(var i=0; i<oNode.childNodes.length;
void objNodeResult.appendChild(
}
if(oNode.nodeType == 3)
{
objNodeResult = document.createTextNode(oN
}
return objNodeResult;
}
--------------------------
this function chages to
--------------------------
this.fromXmlDomNode = function(oNode)
{
if(oNode==undefined || oNode==null || oNode.nodeName!="div")
return;
this.element = this.importNode(oNode)
}
--------------------------
now i can write partial HTML document in the xml file, but another problem shows the style attribute doesnt work with IE
ASKER
last changes to the importNode function
-------------------------- -
this.importNode = function(oNode)
{
if(oNode==undefined || oNode==null)
return null;
var objNodeResult = null;
var blnMs = (navigator.appName.toLower Case().ind exOf("micr osoft")!=- 1);
if(oNode.nodeType == 1)
{
objNodeResult = document.createElement(oNo de.nodeNam e);
for(var i=0; i<oNode.attributes.length; i++)
{
if(blnMs && (oNode.attributes[i].name. toLowerCas e() == "class" || oNode.attributes[i].name.t oLowerCase () == "style" || oNode.attributes[i].name.s ubstr(0,2) .toLowerCa se()=="on" ))
{
if(oNode.attributes[i].nam e.toLowerC ase() == "class")
objNodeResult.className = oNode.attributes[i].value;
if(oNode.attributes[i].nam e.toLowerC ase() == "style")
objNodeResult.style.cssTex t = oNode.attributes[i].value;
if(oNode.attributes[i].nam e.substr(0 ,2).toLowe rCase()==" on")
objNodeResult[oNode.attrib utes[i].na me] = new Function(oNode.attributes[ i].value);
}
else
{
void objNodeResult.setAttribute (oNode.att ributes[i] .name, oNode.attributes[i].value)
}
}
for(var i=0; i<oNode.childNodes.length; i++)
void objNodeResult.appendChild( this.impor tNode(oNod e.childNod es[i]));
}
if(oNode.nodeType == 3)
{
objNodeResult = document.createTextNode(oN ode.nodeVa lue);
}
return objNodeResult;
}
-------------------------- -
class, style and events can be declared in the xml file :)
--------------------------
this.importNode = function(oNode)
{
if(oNode==undefined || oNode==null)
return null;
var objNodeResult = null;
var blnMs = (navigator.appName.toLower
if(oNode.nodeType == 1)
{
objNodeResult = document.createElement(oNo
for(var i=0; i<oNode.attributes.length;
{
if(blnMs && (oNode.attributes[i].name.
{
if(oNode.attributes[i].nam
objNodeResult.className = oNode.attributes[i].value;
if(oNode.attributes[i].nam
objNodeResult.style.cssTex
if(oNode.attributes[i].nam
objNodeResult[oNode.attrib
}
else
{
void objNodeResult.setAttribute
}
}
for(var i=0; i<oNode.childNodes.length;
void objNodeResult.appendChild(
}
if(oNode.nodeType == 3)
{
objNodeResult = document.createTextNode(oN
}
return objNodeResult;
}
--------------------------
class, style and events can be declared in the xml file :)
ASKER
thanx for the comments
Thanks for the points and for the feedback.