Solved

[MSXML] Copying XHTML node to the document

Posted on 2004-04-15
15
421 Views
Last Modified: 2013-12-16
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?
0
Comment
Question by:MMeijer
  • 6
  • 4
  • 4
  • +1
15 Comments
 
LVL 5

Expert Comment

by:alambres
Comment Utility
send code, please
0
 
LVL 5

Author Comment

by:MMeijer
Comment Utility
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("div");
      
      this.fromXmlFile = function(sXml)
      {
            var blnMs     = (navigator.appName.toLowerCase().indexOf("microsoft")!=-1);
            var blnLoaded = false;
            var objXmlDoc = null;

            if(blnMs)
                  objXmlDoc = new ActiveXObject("microsoft.xmldom");
            else
                  objXmlDoc = document.implementation.createDocument("", "", null);

            objXmlDoc.async = false;

            blnLoaded = objXmlDoc.load(sXml)
            
            if(!blnLoaded)
            {
                  var strErrMessage = "Failed to load XML";
                  if(objXmlDoc.parseError)
                        strErrMessage += ", reason: " + objXmlDoc.parseError.reason;

                  return this.onerror(strErrMessage);
            }
            void this.fromXmlDomNode(objXmlDoc.documentElement);
      }

      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("test.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
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
The tree model is slightly different in both browsers, so we need the code to help you speciffic.

0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
You have to extend the render() method:

   
     this.render = function(oParent){
         objParent = (oParent)? oParent: document.body;
         newNode = document.createElement(this.element.nodeName);
         txtNode = document.createTextNode(this.element.text);
         newNode.appendChild(txtNode);
         objParent.appendChild(newNode);
    }


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




0
 
LVL 5

Expert Comment

by:alambres
Comment Utility
what about attributes? This way you'd lost'em
0
 
LVL 5

Expert Comment

by:alambres
Comment Utility
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(this.element.nodeName);
         newNode.innerHTML =  (navigator.appName == 'Netscape')?this.element.innerHTML:this.element.text;
         objParent.appendChild(newNode);
      }

can't make it work in Opera
0
 
LVL 63

Assisted Solution

by:Zvonko
Zvonko earned 250 total points
Comment Utility
Or you move to copy functionality in the create function.
Like this:


    this.fromXmlDomNode = function(oNode){
         if(oNode==undefined || oNode==null || oNode.nodeName!="div")
              return;

         newNode = document.createElement(oNode.nodeName);
         txtNode = document.createTextNode(oNode.firstChild.nodeValue);
         newNode.appendChild(txtNode);
         this.element = newNode;
    }
   
     this.render = function(oParent){
         objParent = oParent? oParent: document.body;
         void objParent.appendChild(this.element);
    }

0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
And the last is tested in IE6.0 and Mozilla1.5
0
 
LVL 5

Accepted Solution

by:
alambres earned 250 total points
Comment Utility
we're getting lost the attributes. You'll see, change the sample xml :
<div style="color:red" xmlns="http://www.w3.org/1999/xhtml">Hello world!</div>

no red font!
0
 
LVL 7

Expert Comment

by:searlas
Comment Utility
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.
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Generally does this question belong into XML topic area:
http://www.experts-exchange.com/Web/Web_Languages/XML/

0
 
LVL 5

Author Comment

by:MMeijer
Comment Utility
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(oNode.nodeName);
                  for(var i=0; i<oNode.attributes.length; i++)
                        void objNodeResult.setAttribute(oNode.attributes[i].name, oNode.attributes[i].value)

                  for(var i=0; i<oNode.childNodes.length; i++)
                        void objNodeResult.appendChild(this.importNode(oNode.childNodes[i]));
            }
            
            if(oNode.nodeType == 3)
            {
                  objNodeResult = document.createTextNode(oNode.nodeValue);
            }

            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
0
 
LVL 5

Author Comment

by:MMeijer
Comment Utility
last changes to the importNode function
---------------------------

      this.importNode = function(oNode)
      {
            if(oNode==undefined || oNode==null)
                  return null;

            var objNodeResult = null;
            var blnMs     = (navigator.appName.toLowerCase().indexOf("microsoft")!=-1);

            if(oNode.nodeType == 1)
            {
                  objNodeResult = document.createElement(oNode.nodeName);
                  for(var i=0; i<oNode.attributes.length; i++)
                  {
                        if(blnMs && (oNode.attributes[i].name.toLowerCase() == "class" || oNode.attributes[i].name.toLowerCase() == "style" || oNode.attributes[i].name.substr(0,2).toLowerCase()=="on"))
                        {
                              if(oNode.attributes[i].name.toLowerCase() == "class")
                                    objNodeResult.className = oNode.attributes[i].value;

                              if(oNode.attributes[i].name.toLowerCase() == "style")
                                    objNodeResult.style.cssText = oNode.attributes[i].value;
                              
                              if(oNode.attributes[i].name.substr(0,2).toLowerCase()=="on")
                                    objNodeResult[oNode.attributes[i].name] = new Function(oNode.attributes[i].value);
                              

                        }
                        else
                        {
                              void objNodeResult.setAttribute(oNode.attributes[i].name, oNode.attributes[i].value)
                        }      
                  }

                  for(var i=0; i<oNode.childNodes.length; i++)
                        void objNodeResult.appendChild(this.importNode(oNode.childNodes[i]));
            }
            
            if(oNode.nodeType == 3)
            {
                  objNodeResult = document.createTextNode(oNode.nodeValue);
            }

            return objNodeResult;
      }
---------------------------

class, style and events can be declared in the xml file :)
0
 
LVL 5

Author Comment

by:MMeijer
Comment Utility
thanx for the comments
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Thanks for the points and for the feedback.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction HTML checkboxes provide the perfect way for a web developer to receive client input when the client's options might be none, one or many.  But the PHP code for processing the checkboxes can be confusing at first.  What if a checkbox is…
This article discusses the difference between strict equality operator and equality operator in JavaScript. The Need: Because JavaScript performs an implicit type conversion when performing comparisons, we have to take this into account when wri…
The purpose of this video is to demonstrate how to integrate Mailchimp with WordPress, by placing a Mailchimp signup form on a WordPress Page or Post. This will be demonstrated using a Windows 8 PC. Mailchimp will be used. Log into your Mailchi…
The purpose of this video is to demonstrate how to set up the permalinks on a WordPress Website. This will be demonstrated using a Windows 8 PC. Go to your WordPress login page. This will look like the following: mywebsite.com/wp-login.php : Go t…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now