123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- if (!dojo._hasResource["dojox.xml.DomParser"]) { // _hasResource checks added
- // by build. Do not use
- // _hasResource directly in
- // your code.
- dojo._hasResource["dojox.xml.DomParser"] = true;
- dojo.provide("dojox.xml.DomParser");
- dojox.xml.DomParser = new (function() {
- /***********************************************************************
- * The DomParser is a close-to (but not entirely) conforming XML parser
- * based on regular expressions. It will take any XML fragment and
- * return a lightweight JS structure that is similar to (but not
- * exactly) the DOM specification.
- *
- * Getter and setter methods are NOT available; the goal was to keep the
- * resulting object model entirely JS-like.
- *
- * All node types but document fragments are supported; all nodes
- * support getElementsByTagName and getElementsByTagNameNS (with short
- * names byName and byNameNS). The document node supports getElementById
- * (byId), and all nodes support a supplimental
- * childrenByName/childrenByNameNS method as well.
- *
- * The object model is intended to be a READONLY format; mutation events
- * are NOT supported, and though you can change properties on a
- * node-by-node basis, certain operations are not supported (such as
- * changing the ID of an element).
- **********************************************************************/
- // internal use only.
- var nodeTypes = {
- ELEMENT : 1,
- ATTRIBUTE : 2,
- TEXT : 3,
- CDATA_SECTION : 4,
- PROCESSING_INSTRUCTION : 7,
- COMMENT : 8,
- DOCUMENT : 9
- };
- // compile the regular expressions once.
- var reTags = /<([^>\/\s+]*)([^>]*)>([^<]*)/g;
- var reAttr = /([^=]*)="([^"]*)"/g;
- var reEntity = /<!ENTITY\s+([^"]*)\s+"([^"]*)">/g;
- var reCData = /<!\[CDATA\[([\u0001-\uFFFF]*?)\]\]>/g;
- var reComments = /<!--([\u0001-\uFFFF]*?)-->/g;
- var trim = /^\s+|\s+$/g;
- var normalize = /\s+/g;
- var egt = /\>/g;
- var elt = /\</g;
- var equot = /\"/g;
- var eapos = /\'/g;
- var eamp = /\&/g;
- var dNs = "_def_";
- // create a root node.
- function _doc() {
- return new (function() {
- var all = {};
- this.nodeType = nodeTypes.DOCUMENT;
- this.nodeName = "#document";
- this.namespaces = {};
- this._nsPaths = {};
- this.childNodes = [];
- this.documentElement = null;
- // any element with an ID attribute will be added to the
- // internal hashtable.
- this._add = function(obj) {
- if (typeof(obj.id) != "undefined") {
- all[obj.id] = obj;
- }
- };
- this._remove = function(id) {
- if (all[id]) {
- delete all[id];
- }
- };
- this.byId = this.getElementById = function(id) {
- return keys[id];
- };
- this.byName = this.getElementsByTagName = byName;
- this.byNameNS = this.getElementsByTagNameNS = byNameNS;
- this.childrenByName = childrenByName;
- })();
- }
- // functions attached to element nodes
- function byName(name) {
- // return all descendants with name. Fully qualified (i.e. svg:svg)
- function __(node, name, arr) {
- dojo.forEach(node.childNodes, function(c) {
- if (c.nodeType == nodeTypes.ELEMENT) {
- if (name == "*") {
- arr.push(c);
- } else if (c.nodeName == name) {
- arr.push(c);
- }
- __(c, name, arr);
- }
- });
- }
- var a = [];
- __(this, name, a);
- return a;
- }
- function byNameNS(name, ns) {
- // return all descendants with name by namespace. If no namespace
- // passed, the default is used.
- function __(node, name, ns, arr) {
- dojo.forEach(node.childNodes, function(c) {
- if (c.nodeType == nodeTypes.ELEMENT) {
- if (name == "*"
- && c.ownerDocument._nsPaths[ns] == c.namespace) {
- arr.push(c);
- } else if (c.localName == name
- && c.ownerDocument._nsPaths[ns] == c.namespace) {
- arr.push(c);
- }
- __(c, name, ns, arr);
- }
- });
- }
- if (!ns) {
- ns = dNs;
- }
- var a = [];
- __(this, name, ns, a);
- return a;
- }
- // Only child nodes with name.
- function childrenByName(name) {
- var a = [];
- dojo.forEach(this.childNodes, function(c) {
- if (c.nodeType == nodeTypes.ELEMENT) {
- if (name == "*") {
- a.push(c);
- } else if (c.nodeName == name) {
- a.push(c);
- }
- }
- });
- return a;
- }
- // attribute functions
- function getAttr(name) {
- for (var i = 0; i < this.attributes.length; i++) {
- if (this.attributes[i].nodeName == name) {
- return this.attributes[i].nodeValue;
- }
- }
- return null;
- }
- function getAttrNS(name, ns) {
- for (var i = 0; i < this.attributes.length; i++) {
- if (this.ownerDocument._nsPaths[ns] == this.attributes[i].namespace
- && this.attributes[i].localName == name) {
- return this.attributes[i].nodeValue;
- }
- }
- return null;
- }
- // note that you can only swap IDs using setAttribute, NOT with
- // setAttributeNS.
- function setAttr(name, val) {
- var old = null;
- for (var i = 0; i < this.attributes.length; i++) {
- if (this.attributes[i].nodeName == name) {
- old = this.attributes[i].nodeValue;
- this.attributes[i].nodeValue = val;
- break;
- }
- }
- if (name == "id") {
- if (old != null) {
- this.ownerDocument._remove(old);
- }
- this.ownerDocument._add(this);
- }
- }
- function setAttrNS(name, val, ns) {
- for (var i = 0; i < this.attributes.length; i++) {
- if (this.ownerDocument._nsPaths[ns] == this.attributes[i].namespace
- && this.attributes[i].localName == name) {
- this.attributes[i].nodeValue = val;
- return;
- }
- }
- }
- // navigation
- function prev() {
- var p = this.parentNode;
- if (p) {
- for (var i = 0; i < p.childNodes.length; i++) {
- if (p.childNodes[i] == this && i > 0) {
- return p.childNodes[i - 1];
- }
- }
- }
- return null;
- }
- function next() {
- var p = this.parentNode;
- if (p) {
- for (var i = 0; i < p.childNodes.length; i++) {
- if (p.childNodes[i] == this
- && (i + 1) < p.childNodes.length) {
- return p.childNodes[i + 1];
- }
- }
- }
- return null;
- }
- // the main method.
- this.parse = function(/* String */str) {
- var root = _doc();
- if (str == null) {
- return root;
- }
- if (str.length == 0) {
- return root;
- }
- // preprocess custom entities
- if (str.indexOf("<!ENTITY") > 0) {
- var entity, eRe = [];
- if (reEntity.test(str)) {
- reEntity.lastIndex = 0;
- // match entities
- while ((entity = reEntity.exec(str)) != null) {
- eRe.push({
- entity : "&" + entity[1].replace(trim, "")
- + ";",
- expression : entity[2]
- });
- }
- // replace instances in the document.
- for (var i = 0; i < eRe.length; i++) {
- str = str.replace(new RegExp(eRe[i].entity, "g"),
- eRe[i].expression);
- }
- }
- }
- // pre-parse for CData, and tokenize.
- var cdSections = [], cdata;
- while ((cdata = reCData.exec(str)) != null) {
- cdSections.push(cdata[1]);
- }
- for (var i = 0; i < cdSections.length; i++) {
- str = str.replace(cdSections[i], i);
- }
- // pre-parse for comments, and tokenize.
- var comments = [], comment;
- while ((comment = reComments.exec(str)) != null) {
- comments.push(comment[1]);
- }
- for (i = 0; i < comments.length; i++) {
- str = str.replace(comments[i], i);
- }
- // parse the document
- var res, obj = root;
- while ((res = reTags.exec(str)) != null) {
- // closing tags.
- if (res[2].charAt(0) == "/") {
- if (obj.parentNode) {
- obj = obj.parentNode;
- }
- continue;
- }
- // open tags.
- if (res[1].length > 0) {
- // figure out the type of node.
- if (res[1].charAt(0) == "?") {
- // processing instruction
- var name = res[1].substr(1);
- var target = res[2].substr(0, res[2].length - 2);
- obj.childNodes.push({
- nodeType : nodeTypes.PROCESSING_INSTRUCTION,
- nodeName : name,
- nodeValue : target
- });
- } else if (res[1].charAt(0) == "!") {
- // CDATA; skip over any declaration elements.
- if (res[1].indexOf("![CDATA[") == 0) {
- var val = parseInt(res[1].replace("![CDATA[", "")
- .replace("]]", ""));
- obj.childNodes.push({
- nodeType : nodeTypes.CDATA_SECTION,
- nodeName : "#cdata-section",
- nodeValue : cdSections[val]
- });
- }
- // Comments.
- else if (res[1].substr(0, 3) == "!--") {
- var val = parseInt(res[1].replace("!--", "")
- .replace("--", ""));
- obj.childNodes.push({
- nodeType : nodeTypes.COMMENT,
- nodeName : "#comment",
- nodeValue : comments[val]
- });
- }
- } else {
- // Elements (with attribute and text)
- var name = res[1].replace(trim, "");
- var o = {
- nodeType : nodeTypes.ELEMENT,
- nodeName : name,
- localName : name,
- namespace : dNs,
- ownerDocument : root,
- attributes : [],
- parentNode : null,
- childNodes : []
- };
- // check to see if it's namespaced.
- if (name.indexOf(":") > -1) {
- var t = name.split(":");
- o.namespace = t[0];
- o.localName = t[1];
- }
- // set the function references.
- o.byName = o.getElementsByTagName = byName;
- o.byNameNS = o.getElementsByTagNameNS = byNameNS;
- o.childrenByName = childrenByName;
- o.getAttribute = getAttr;
- o.getAttributeNS = getAttrNS;
- o.setAttribute = setAttr;
- o.setAttributeNS = setAttrNS;
- o.previous = o.previousSibling = prev;
- o.next = o.nextSibling = next;
- // parse the attribute string.
- var attr;
- while ((attr = reAttr.exec(res[2])) != null) {
- if (attr.length > 0) {
- var name = attr[1].replace(trim, "");
- var val = attr[2].replace(normalize, " ")
- .replace(egt, ">").replace(elt, "<")
- .replace(eapos, "'")
- .replace(equot, '"').replace(eamp, "&");
- if (name.indexOf("xmlns") == 0) {
- if (name.indexOf(":") > 0) {
- var ns = name.split(":");
- root.namespaces[ns[1]] = val;
- root._nsPaths[val] = ns[1];
- } else {
- root.namespaces[dNs] = val;
- root._nsPaths[val] = dNs;
- }
- } else {
- var ln = name;
- var ns = dNs;
- if (name.indexOf(":") > 0) {
- var t = name.split(":");
- ln = t[1];
- ns = t[0];
- }
- o.attributes.push({
- nodeType : nodeTypes.ATTRIBUTE,
- nodeName : name,
- localName : ln,
- namespace : ns,
- nodeValue : val
- });
- // only add id as a property.
- if (ln == "id") {
- o.id = val;
- }
- }
- }
- }
- root._add(o);
- var text = res[3].replace(trim, "");
- if (text.length > 0)
- o.childNodes.push({
- nodeType : nodeTypes.TEXT,
- nodeName : "#text",
- nodeValue : text
- .replace(normalize, " ")
- .replace(egt, ">").replace(elt,
- "<")
- .replace(eapos, "'").replace(
- equot, '"').replace(
- eamp, "&")
- });
- if (obj) {
- obj.childNodes.push(o);
- o.parentNode = obj;
- // if it's not a self-closing node.
- if (res[2].charAt(res[2].length - 1) != "/") {
- obj = o;
- }
- }
- }
- }
- }
- // set the document element
- for (var i = 0; i < root.childNodes.length; i++) {
- var e = root.childNodes[i];
- if (e.nodeType == nodeTypes.ELEMENT) {
- root.documentElement = e;
- break;
- }
- }
- return root;
- };
- })();
- }
|