The Other Worlds Shrine

Your place for discussion about RPGs, gaming, music, movies, anime, computers, sports, and any other stuff we care to talk about... 

  • JavaScript true AJAX

  • Somehow, we still tolerate each other. Eventually this will be the only forum left.
Somehow, we still tolerate each other. Eventually this will be the only forum left.
 #128451  by SineSwiper
 
Some people recommend against XML to XML communication between server and client, because building XML in JavaScript is "hard". I did it anyway, because it's actually easier to have the same XML standard for both directions. I'll post this because some people might find it useful for pure AJAX programming:
Code: Select all
/////////////
// XML subs

function CreateXMLObj (rName) {
   if (document.implementation && document.implementation.createDocument) {
      // Gecko-based browsers: Firefox, Safari, Opera, etc.
      xmlDoc = document.implementation.createDocument("",rName,null);
      xmlDoc.async = 'false';
      return xmlDoc;
   }
   else if (window.ActiveXObject) {
      // Internet Explorer
      xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
      xmlDoc.async = "false";
      var root = xmlDoc.createElement(rName);
      xmlDoc.documentElement = root;
      return xmlDoc;
   }
   else {
      alert("Browser incompatibility: CreateXMLObj");
   }
   return false;
}

function Str2XML (xmlStr) {
   if (window.DOMParser) {
      // Gecko-based browsers: Firefox, Safari, Opera, etc.
      xmlDoc = (new DOMParser()).parseFromString(text, "text/xml");
      return xmlDoc;
   }
   else if (window.ActiveXObject) {
      // Internet Explorer
      xmlDoc = CreateXMLObj();
      xmlDoc.loadXML(xmlStr);
      return xmlDoc;
   }
   else {
      alert("Browser incompatibility: Str2XML");
   }
   return false;
}

function XML2Str (xmlDoc) {
   if (window.XMLSerializer) {
      // Gecko-based browsers: Firefox, Safari, Opera, etc.
      return XML((new XMLSerializer()).serializeToString(xmlDoc)).toXMLString();
   }
   else if (xmlDoc.xml) {
      // Internet Explorer
      return XMLIndentLoop(xmlDoc.xml.replace(/>(?=<\/?\w+)/g, ">\n"));
   }
   else {
      alert("Browser incompatibility: XML2Str");
   }
   return false;
}

function XMLIndentLoop (xmlStr) {
   // Find root and remove it (temporarily)
   //var oldStr = xmlStr;
   var root = xmlStr.match(/^(\s*<(\w+)[^\<\>]*>[ ]*\n?)[\s\S]+?([ ]*</2>\n?)/);
   xmlStr = xmlStr.replace(/^\s*<(\w+)[^\<\>]*>[ ]*\n?([\s\S]+?)[ ]*</1>\n?/, "$2");

   // Recursively loop into sub-blocks
   xmlStr = xmlStr.replace(/>\n(?=[ ]*<\/?\w+)/g, ">\n   ");  // insert spaces into current block
   // alert("OLD:\n" + oldStr + "\nROOT:\n" + root[1] + "\nROOT:\n" + root[3] + "\nXML:\n   " + xmlStr);

   var blocks = xmlStr.match(/\s*<(\w+)[^\<\>]*>[\s\S]+</1>\n|\s*<\w+[^\<\>]*\/>\n/g);  // match on node blocks and standalone tags
   if (blocks) {
      for (var i = 0; i < blocks.length; i++) {
         if (blocks[i].match(/<(\w+)[^\<\>]*>[\s\S]+</1>/)) blocks[i] = XMLIndentLoop(blocks[i]);  // throw any blocks into the indent loop
      }
      return root[1] + "   " + blocks.join("") + root[3];  // both blocks and standalones get the beginning space indentation
   }
   else {
      return root[1] + xmlStr + root[3];  // real data inside the tag, so keep it
   }
}

function XMLCreateElement (xmlDoc, dest, name, value) {
   var el = xmlDoc.createElement(name);
   if (value) {
      var text = xmlDoc.createTextNode(value);
      el.appendChild(text);
   }
   dest.appendChild(el);
   return dest.lastChild;
}

function XMLUpdateElement (xmlDoc, dest, name, value) {
   var el = dest.getElementsByTagName(name)[0];
   if (el) {  // check for tag
      if (el.firstChild) {  // check for text node
         el.firstChild.nodeValue = value;
      }
      else if (value) {
         var text = xmlDoc.createTextNode(value);
         el.appendChild(text);
      }
      
      return el;
   }
   else {
      return XMLCreateElement(xmlDoc, dest, name, value);
   }
   
   return false;
}

 #128472  by Shellie
 
Too much nerd for one post!

 #128474  by Lox
 
I will read this and look at the code...just not at work where I'm writing and analyzing different code already. :)

 #128614  by SineSwiper
 
Still having problems with getting the indents to work right. Even had it working with processor instructions (<? > stuff). But, IE wouldn't work right with certain cases. So, I gave up and found a better ActiveX object to handle it:
Code: Select all
function XML2Str (xmlDoc) {
   if (window.XMLSerializer) {
      // Gecko-based browsers: Firefox, Safari, Opera, etc.
      try {  // might get tripped up on ?xml tags
         return XML((new XMLSerializer()).serializeToString(xmlDoc)).toXMLString();
      }
      catch (e)
      {
         return (new XMLSerializer()).serializeToString(xmlDoc);
      }
   }
   else if (xmlDoc.xml) {
      // Internet Explorer
      // try {  // in case the ActiveX Objects don't exist
         var reader = new ActiveXObject("Msxml2.SAXXMLReader.4.0");
         var writer = new ActiveXObject("Msxml2.MXXMLWriter.4.0");
         writer.indent = true;
         writer.standalone = true;
         reader.contentHandler = writer;
         reader.putProperty("http://xml.org/sax/properties/lexical-handler", writer);
         reader.parse(xmlDoc);
         return writer.output;
      /*}
      catch (e)
      {
         return xmlDoc.xml.replace(/>(?=<\/?\w+)/g, ">\n");
      }*/
   }
   else {
      alert("Browser incompatibility: XML2Str");
   }
   return false;
}