modules/js/htdocs/xmlutil.js (125 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * XML handling functions. */ /** * Append a list of nodes to a parent node. */ function appendNodes(nodes, p) { if (isNull(nodes)) return p; p.appendChild(car(nodes)); return appendNodes(cdr(nodes), p); } /** * Return the child attributes of an element. */ function childAttributes(e) { return filter(function(n) { return n.nodeType == 2; }, nodeList(e.attributes)); } /** * Return the child elements of an element. */ function childElements(e) { return filter(function(n) { return n.nodeType == 1; }, nodeList(e.childNodes)); } /** * Return the child text nodes of an element. */ function childText(e) { return filter(function(n) { return n.nodeType == 3 && n.nodeValue.trim().length != 0; }, nodeList(e.childNodes)); } /** * Read a list of XML attributes. */ function readAttributes(a) { if (isNull(a)) return a; var x = car(a); return cons(mklist(attribute, "'" + x.name, x.value), readAttributes(cdr(a))); } /** * Read an XML element. */ function readElement(e, childf) { var l = append(append(mklist(element, "'" + e.nodeName), readAttributes(childf(e))), readElements(childElements(e), childf)); var t = childText(e); if (isNull(t)) return l; var tv = reduce(function(a, n) { return a + n.nodeValue; }, '', t); return append(l, mklist(tv)); } /** * Read a list of XML elements. */ function readElements(l, childf) { if (isNull(l)) return l; return cons(readElement(car(l), childf), readElements(cdr(l), childf)); } /** * Return true if a list of strings contains an XML document. */ function isXML(l) { if (isNull(l)) return false; return car(l).substring(0, 5) == '<?xml'; } /** * Parse a list of strings representing an XML document. */ var xmlParser = new DOMParser(); function parseXML(l) { var s = writeStrings(l); return xmlParser.parseFromString(s, "text/xml"); } /** * Read a list of values from an XML document. */ function readXMLDocument(doc) { var root = childElements(doc); if (isNull(root)) return nil; return mklist(readElement(car(root), childAttributes)); } /** * Read a list of values from an XHTML element. */ function readXHTMLElement(xhtml) { return mklist(readElement(xhtml, childAttributes)); } /** * Read a list of values from a list of strings representing an XML document. */ function readXML(l) { return readXMLDocument(parseXML(l)); } /** * Return a list of strings representing an XML document. */ var xmlSerializer = new XMLSerializer(); function writeXMLDocument(doc) { return mklist(xmlSerializer.serializeToString(doc)); } /** * Write a list of XML element and attribute tokens. */ function expandElementValues(n, l) { if (isNull(l)) return l; return cons(cons(element, cons(n, car(l))), expandElementValues(n, cdr(l))); } function writeList(l, node, doc) { if (isNull(l)) return node; var token = car(l); if (isTaggedList(token, attribute)) { if (isMSIE()) { var aname = attributeName(token).substring(1); if (aname != 'xmlns') node.setAttribute(aname, '' + attributeValue(token)); } else node.setAttribute(attributeName(token).substring(1), '' + attributeValue(token)); } else if (isTaggedList(token, element)) { function mkelem(tok, doc) { function xmlns(l) { if (isNull(l)) return null; var t = car(l); if (isTaggedList(t, attribute)) { if (attributeName(t).substring(1) == 'xmlns') return attributeValue(t); } return xmlns(cdr(l)); } var ns = xmlns(elementChildren(tok)); if (isMSIE()) return doc.createElementNS(ns != null? ns : node.namespaceURI, elementName(tok).substring(1)); if (ns == null) return doc.createElement(elementName(tok).substring(1)); return doc.createElementNS(ns, elementName(tok).substring(1)); } if (elementHasValue(token)) { var v = elementValue(token); if (isList(v)) { var e = expandElementValues(elementName(token), v); writeList(e, node, doc); } else { var child = mkelem(token, doc); writeList(elementChildren(token), child, doc); node.appendChild(child); } } else { var child = mkelem(token, doc); writeList(elementChildren(token), child, doc); node.appendChild(child); } } else node.appendChild(doc.createTextNode('' + token)); writeList(cdr(l), node, doc); return node; } /** * Make a new XML document. */ function mkXMLDocument() { return document.implementation.createDocument('', '', null); } /** * Convert a list of values to a list of strings representing an XML document. */ function writeXML(l, xmlTag) { var doc = mkXMLDocument(); writeList(l, doc, doc); if (!xmlTag) return writeXMLDocument(doc); return mklist('<?xml version="1.0" encoding="UTF-8"?>\n' + car(writeXMLDocument(doc)) + '\n'); }