Simple serialization with XML strings in Javascript

Introduction

Included in this post are some quick and simple functions for doing XML serialization in Javascript through strings. Reserved XML characters < > & ' " are escaped from input and if any invalid input are found an exception will be thrown.

List of XML utility functions:

  • toXmlHeader() – Creates the XML header.
  • toXmlElem(name: string, attributes: object) – Creates and closes an XML element.
  • toXmlElemOpen(name: string, attributes: object) – Creates and opens an XML element.
  • toXmlElemClose(name: string) – Closes an XML element.
  • toXmlText(text: string) – Creates XML text.

A serialization example

var xml = toXmlHeader();
xml += toXmlElemOpen("Library"); // No attributes given.
 
xml += toXmlElemOpen("Authors", {country: "Norway"});
xml += toXmlElem("Author", {name:"Petter Dass"});
xml += toXmlElemClose("Authors");
 
xml += toXmlElemOpen("Books"); // No attributes given.
xml += toXmlElem("Book", {title:"book1", author:"author1"});
xml += toXmlElemOpen("Book", {title:"book2", author:"author1"});
xml += toXmlText("Ach, So?");
xml += toXmlElemClose("Book");
xml += toXmlElem("Book", {title:"book3", author:"author2"});
xml += toXmlElem("Book"); // No attributes given.
xml += toXmlElemClose("Books");
 
xml += toXmlElemClose("Library");
alert(xml); // the complete xml is now contained inside the string.
<?xml version="1.0" encoding="UTF-8"?>
<Library>
<Authors country="Norway">
<Author name="Petter Dass"/></Authors>
<Books>
<Book title="book1" author="author1"/>
<Book title="book2" author="author1">Ach, So?</Book>
<Book title="book3" author="author2"/>
<Book/></Books></Library>

Sourcecode for the XML utility functions

function toXmlValid(str) {
  if (str === undefined || str === null || str.match === undefined || str.match(/<|>|&|'|"/) !== null) {
    throw("invalid string given");
  }
 
  return str;
}
 
function escapeXmlText(str) {
  if (str === undefined || str === null || str.replace === undefined) {
    throw("invalid string given");
  }
 
  // The order of replace is important because the & character is used in escaping.
  return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/'/g, "&apos;");
}
 
function unescapeXmlText(str) {
  if (str === undefined || str === null || str.replace === undefined) {
    throw("invalid string given");
  }
 
  // The order of replace is important because the & character is used in unescaping.
  return str.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&apos;/g, "'").replace(/&quot;/g, "\"").replace(/&amp;/g, "&");
}
 
function toXmlHeader() {
  return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
}
 
function toXmlAttr(name, value) {
  return " " + toXmlValid(name) + "=\"" + escapeXmlText(value) + "\"";
}
 
function toXmlElem(tagName, attributes) {
  var str = "\n<" + toXmlValid(tagName);
 
  if (attributes !== undefined) {	
    for (var key in attributes) {
      if (attributes.hasOwnProperty(key) === true) {
        str += toXmlAttr(key, attributes[key]);
      }
    }
  }
 
  return str + "/>";
}
 
function toXmlElemOpen(tagName, attributes) {
  var str = "\n<" + toXmlValid(tagName);
 
  if (attributes !== undefined) {
    for (var key in attributes) {
      if (attributes.hasOwnProperty(key) === true) {
        str += toXmlAttr(key, attributes[key]);
      }
    }
  }
 
  return str + ">";
}
 
function toXmlElemClose(tagName) {
  return "</" + toXmlValid(tagName) + ">";
}
 
function toXmlText(text) {
  return escapeXmlText(text);
}

References

Leave a Reply

Your email address will not be published. Required fields are marked *