Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 10 of 10
  1. #1
    Smokes a Lot
    Join Date
    Jul 2003
    Location
    CA, USA
    Posts
    1,594
    Thanks
    5
    Thanked 20 Times in 20 Posts

    XML to XHTML Transformation

    In the past whenever I needed to get a bit of data from the server through an xmlHTTPRequest, I could do one of two things:

    Serve my self up the data in xml and then parse through each xml tag and create an appropriate html tag. In turn appending any applicable data to each html element. -- Big hassle but imho the right way.

    The other way (the dirty way) to just get the responseText and change the innerHTML of my target element. -- Nice and easy but dirty.

    Now I thought, it sure would be nice if there was a responseXHTML that I could traverse to get the top node of the xhtml that I am interested in and simply append that to my target dom node.

    There is no such thing that I am aware of, but I've come up with the following that attempts to do just that. It all seems to be working for the most part, however, it's appending an undefined element to the target node, it is unaparent when rendered in the browser window, but in the DOM inspector it is viewable. I'd also appreciate any feedback on things I may not have taken into consideration.


    Below is the code that parses the XML:
    Code:
    function toXHTML(obj){
    	var div=document.createElement("div");
    	makeChild(obj,div);
    	function makeChild(src_xml,targ_html){
    		var new_html=transformXML(src_xml);
    		targ_html.appendChild(new_html);
    		var kids=src_xml.childNodes;
    		var len=kids.length;
    		for(var i=0;i<len;i++){
    			makeChild(kids[i],new_html);
    		}
    	}
    	return div;
    }
    function transformXML(obj){
    	if(obj.tagName){
    		var ie = (document.all && !window.opera)?1:0;
    		var flg=0;
    		if(ie){
    			if(obj.tagName.toLowerCase()=="input"){
    				if(obj.getAttribute('type').toLowerCase()=="radio"||obj.getAttribute('type').toLowerCase()=="checkbox"){
    					var flg=1;
    					var html_obj=document.createElement('<'+obj.tagName+' name='+obj.getAttribute("name")+'" />');	
    				}else{
    					var html_obj=document.createElement(obj.tagName);
    				}
    			}else{
    				var html_obj=document.createElement(obj.tagName);
    			}
    		}else{
    			var html_obj=document.createElement(obj.tagName);
    		}
    		var atts=obj.attributes;
    		var len=atts.length;
    		for(var i=0;i<len;i++){
    			switch(atts[i].name.toLowerCase()){
    				case "name":
    					if(flg==0){
    						html_obj.name=atts[i].value;
    					}
    				break;
    				case "class":
    					html_obj.className=atts[i].value;
    				break;
    				case "value":
    					html_obj.value=atts[i].value;
    				break;
    				case "colspan":
    					html_obj.setAttribute("colSpan",atts[i].value);
    				break;
    				default:
    					html_obj.setAttribute(atts[i].name.toLowerCase(),atts[i].value);	
    			}
    		}
    	}else{
    		html_obj=document.createTextNode(obj.nodeValue);	
    	}
    	return html_obj;
    }
    Please note if you try to use this, it isn't expecting event handlers in your tags, event handlers can be added from script on the calling page.
    Last edited by Basscyst; 03-15-2007 at 11:16 PM.
    Helping to build a bigger box. - Adam Matthews

  • #2
    jkd
    jkd is offline
    Senior Coder jkd's Avatar
    Join Date
    May 2002
    Location
    metro DC
    Posts
    3,163
    Thanks
    1
    Thanked 18 Times in 18 Posts
    Just return well-formed XHTML markup to the request, then you can do a DOM traversal to the node you want, call it myNode, and then say
    Code:
    myNode = document.importNode(myNode, true);
    so that you can append it (some browsers don't require importNode, and may in fact throw an error about it... something to detect)) directly into the current document. No need to parse anything.

  • #3
    Smokes a Lot
    Join Date
    Jul 2003
    Location
    CA, USA
    Posts
    1,594
    Thanks
    5
    Thanked 20 Times in 20 Posts
    Ha! That's awesome, now I wish I didn't take the day off today. So you are saying importNode will make it so when I append the xml node, which is xhtml, it will treat it as html and display properly in the page? If so, that's gonna make things way easier.
    Helping to build a bigger box. - Adam Matthews

  • #4
    Senior Coder
    Join Date
    Nov 2006
    Posts
    1,000
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I don't think IE supports importNode unfortunately.

    david_kw

  • #5
    Senior Coder
    Join Date
    Nov 2006
    Posts
    1,000
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I know this has nothing really innovative in it but to keep things abstracted I have done something like the below example. This way you use the browsers parser and don't have to recreate it. The code, of course, has to be more dynamic if for some reason the stringXHTML doesn't have a rootNode.

    Code:
    function createXHTMLNode(stringXHTML) {
      var div = document.createElement("div");
      div.innerHTML = stringXHTML;
    
      return(div.firstChild);
    }
    
    var rootNode = createXHTMLNode(xhr.responseText);
    document.getElementById("mydiv").appendChild(rootNode);
    Then you could swap out there "right" way in function createXML with importNode if it is there or whatever else makes sense for your data. It is of course identical to setting the innerHTML of mydiv but it makes me feel better about using it. :)

    david_kw

  • #6
    Smokes a Lot
    Join Date
    Jul 2003
    Location
    CA, USA
    Posts
    1,594
    Thanks
    5
    Thanked 20 Times in 20 Posts
    Yeah, it doesn't seem to work in IE. So it seems I still have use for my code above. Any ideas as to why it's appending an undefined node to the document?

    david_kw-I've done that trick before but it kind of defeats the purpose.

    Edit:
    Heh - I'm lame, I just didn't have quotes around my first div creation.

    Last edited by Basscyst; 03-12-2007 at 07:28 PM.
    Helping to build a bigger box. - Adam Matthews

  • #7
    Regular Coder
    Join Date
    Apr 2003
    Location
    Montreal, QC
    Posts
    340
    Thanks
    3
    Thanked 2 Times in 2 Posts
    Hi,

    I just came across this thread. You should check out this article: http://www.alistapart.com/articles/c...owserscripting

    It creates a fixed version of importNode() that works cross-browser.

    I'm looking to do something similar, but I also need to be able to have inline javascript tags, that get executed in place, in my imported HTML - for example to serve an advertisement that is invoked with some JS code. Any ideas?
    Search for Laughter or Just Search?
    GiggleSearch.org
    Blog: www.johnbeales.com
    All About Ballet: www.the-ballet.com

  • #8
    Senior Coder
    Join Date
    Nov 2006
    Posts
    1,000
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I think Prototype can do that with their Ajax.Updater() using the option evalScripts = true

    http://www.prototypejs.org/api/ajax/updater

    I haven't looked at the source, but I suspect they are using innerHTML though.

    david_kw

  • #9
    Regular Coder
    Join Date
    Apr 2003
    Location
    Montreal, QC
    Posts
    340
    Thanks
    3
    Thanked 2 Times in 2 Posts
    I just took a look, and it looks like they are using responseText, which means I'll have little or no control over the DOM of my updated page area. Also, it seems that while they will eval() any script blocks, they aren't eval'ed in place, so, for example, a document.write, (which most advertisers still use to insert their ads), won't work correctly, and may actually overwrite the whole page.

    Thanks though. Prototype has some interesting things going on. I think there's stuff to learn there.

    John
    Search for Laughter or Just Search?
    GiggleSearch.org
    Blog: www.johnbeales.com
    All About Ballet: www.the-ballet.com

  • #10
    Smokes a Lot
    Join Date
    Jul 2003
    Location
    CA, USA
    Posts
    1,594
    Thanks
    5
    Thanked 20 Times in 20 Posts
    document.write and ajax don't mix too well as far as I've experienced. Once the page has loaded, evoking document.write will as you said, wipe the page of all but that which is written.

    I usually just keep any code that I need to execute on behalf of an xmlhttp request's response in the page from which it is called. Then I just execute that code in my call back function. If I need to add event handlers to the elements created from the xml, I simply add them from the call back function prior to appending the xhtml to the document.

    Hope that helps,

    Basscyst
    Helping to build a bigger box. - Adam Matthews


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •