Examples

A DOMDocument is the container for a whole XML tree. You create one to build a SOAP payload, an rtEvent, or any structured value, and you parse one to read XML that arrives as text. Its .root is the top 📕 DOMElement, which you read with the DOM API.

Use these DOM methods, never E4X — see the XML overview.

Build XML (ES5)

Start a document with new DOMDocument(rootTag), create nodes on it with createElement(tag), set attributes with setAttribute(name, value), and attach them with appendChild(child). For a whole fragment at once, DOMDocument.fromJXON({...}) maps a plain object to XML — scalars become attributes, nested objects become child elements — which is the ES5 replacement for E4X XML literals.

// Start a document; its root is a DOMElement you can extend
var doc = new DOMDocument("rtEvent");
var root = doc.root;
root.setAttribute("type", "welcome");

// createElement() makes a node owned by the document; appendChild attaches it
var ctxNode = doc.createElement("ctx");
ctxNode.setAttribute("email", "[email protected]");
ctxNode.setAttribute("firstName", "Jane");
root.appendChild(ctxNode);

logInfo(doc.toXMLString());
// <rtEvent type="welcome"><ctx email="[email protected]" firstName="Jane"/></rtEvent>

// DOMDocument.fromJXON builds the same fragment from a plain object - the ES5
// replacement for E4X literals. Scalars become attributes, objects become
// child elements.
var sameDoc = DOMDocument.fromJXON({
  rtEvent: {
    type: "welcome",
    ctx: { email: "[email protected]", firstName: "Jane" },
  },
});
logInfo(sameDoc.toXMLString()); // identical output

Parse XML text

DOMDocument.fromXMLString(xml) turns a string into a document. Reach for .root to get the top DOMElement, then read it with the 📕 DOMElement API.

// Parse XML text into a document
var doc = DOMDocument.fromXMLString(
  '<extAccount name="ftpServer" server="ftp.example.com" active="1"/>'
);

// .root is the top DOMElement; read it with the DOMElement API
var account = doc.root;
logInfo(account.getAttribute("name")); // ftpServer
logInfo(account.$server); // ftp.example.com

Serialize

toXMLString() renders the node back to XML text — compact by default, or pretty-printed when you pass true. It is the fastest way to inspect a node while debugging, paired with 📕 logInfo.

var doc = DOMDocument.fromJXON({
  rtEvent: {
    type: "welcome",
    ctx: { email: "[email protected]" },
  },
});

// Compact, single line - good for storing or sending over SOAP
logInfo(doc.toXMLString());
// <rtEvent type="welcome"><ctx email="[email protected]"/></rtEvent>

// Pretty-printed with indentation - pass true; ideal for debug logs
logInfo(doc.toXMLString(true));
// <rtEvent type="welcome">
//   <ctx email="[email protected]"/>
// </rtEvent>

Going further

Once a document is built or parsed, everything else — iterating children, finding branches, reading attributes — happens on its nodes: see 📕 DOMElement. For the big picture, the XML overview.

Unit tests

Tested with acc by running acc instance exec -f test/integration/DOMDocument.spec.js in a sandbox:

loadLibrary("/nl/core/shared/nl.js"); // import NL.assert
// creation
const xmlDoc = new DOMDocument("tagHere");
context.test1 = NL.assert(typeof xmlDoc === "object");
context.test2 = NL.assert(xmlDoc instanceof DOMDocument);
context.test3 = NL.assert(xmlDoc.toXMLString() === "<?xml version='1.0'?>\n<tagHere/>");
context.test4 = NL.assert(typeof xmlDoc.root === "object");
const newTag = xmlDoc.createElement("newTag"); // no change, must call appendChild
context.test10 = NL.assert(xmlDoc.toXMLString() === "<?xml version='1.0'?>\n<tagHere/>");
xmlDoc.root.appendChild(newTag);
context.test11 = NL.assert(
  xmlDoc.toXMLString() === "<?xml version='1.0'?>\n<tagHere><newTag/></tagHere>"
);
const abcText = xmlDoc.createTextNode("abc"); // no change, must call appendChild
context.test20 = NL.assert(
  xmlDoc.toXMLString() === "<?xml version='1.0'?>\n<tagHere><newTag/></tagHere>"
);
newTag.appendChild(abcText);
context.test21 = NL.assert(
  xmlDoc.toXMLString() === "<?xml version='1.0'?>\n<tagHere><newTag>abc</newTag></tagHere>"
);
// edge values
context.test30 = NL.assert(DOMDocument.fromJXON(null).toXMLString() === "");
context.test31 = NL.assert(DOMDocument.fromJXON("").toXMLString() === "");
context.test32 = NL.assert(DOMDocument.fromJXON("tag").toXMLString() === "");
context.test33 = NL.assert(DOMDocument.fromJXON({}).toXMLString() === "");
context.test34 = NL.assert(DOMDocument.fromJXON([]).toXMLString() === "");
context.test35 = NL.assert(DOMDocument.fromJXON([1, 2]).toXMLString() === "");
context.test36 = NL.assert(DOMDocument.fromJXON({ a: [] }).root.toXMLString() === "<a/>");
context.test37 = NL.assert(DOMDocument.fromJXON({ a: {} }).root.toXMLString() === "<a/>");
// edge keys
context.test40 = NL.assert(DOMDocument.fromJXON({ a: {}, b: {} }).toXMLString() === "");

See also

  • 📕 DOMElement - Adobe Campaign's XML element: the type returned by queryDef and SOAP calls. Can be read and traversed.
  • 📕 queryDef - Helper to run a SQL SELECT query with JSON and returns an XML element.