| 1 |
////// JSXML XML Tools - REXML ///////////// |
| 2 |
////// Regular Expression-based XML parser ///////////// |
| 3 |
////// Ver 1.2 Jun 18 2001 ///////////// |
| 4 |
////// Copyright 2000 Peter Tracey ///////////// |
| 5 |
////// http://jsxml.homestead.com/ ///////////// |
| 6 |
|
| 7 |
function REXML(XML) { |
| 8 |
this.XML = XML; |
| 9 |
|
| 10 |
this.rootElement = null; |
| 11 |
|
| 12 |
this.parse = REXML_parse; |
| 13 |
if (this.XML && this.XML != "") this.parse(); |
| 14 |
} |
| 15 |
|
| 16 |
function REXML_parse() { |
| 17 |
var reTag = new RegExp("<([^>/ ]*)([^>]*)>","g"); // matches that tag name $1 and attribute string $2 |
| 18 |
var reTagText = new RegExp("<([^>/ ]*)([^>]*)>([^<]*)","g"); // matches tag name $1, attribute string $2, and text $3 |
| 19 |
var strType = ""; |
| 20 |
var strTag = ""; |
| 21 |
var strText = ""; |
| 22 |
var strAttributes = ""; |
| 23 |
var strOpen = ""; |
| 24 |
var strClose = ""; |
| 25 |
var iElements = 0; |
| 26 |
var xmleLastElement = null; |
| 27 |
if (this.XML.length == 0) return; |
| 28 |
var arrElementsUnparsed = this.XML.match(reTag); |
| 29 |
var arrElementsUnparsedText = this.XML.match(reTagText); |
| 30 |
var i=0; |
| 31 |
if (arrElementsUnparsed[0].replace(reTag, "$1") == "?xml") i++; |
| 32 |
|
| 33 |
for (; i<arrElementsUnparsed.length; i++) { |
| 34 |
strTag = arrElementsUnparsed[i].replace(reTag,"$1"); |
| 35 |
strAttributes = arrElementsUnparsed[i].replace(reTag,"$2"); |
| 36 |
strText = arrElementsUnparsedText[i].replace(reTagText,"$3").replace(/[\r\n\t ]+/g, " "); // remove white space |
| 37 |
strClose = ""; |
| 38 |
if (strTag.indexOf("![CDATA[") == 0) { |
| 39 |
strOpen = "<![CDATA["; |
| 40 |
strClose = "]]>"; |
| 41 |
strType = "cdata"; |
| 42 |
} else if (strTag.indexOf("!--") == 0) { |
| 43 |
strOpen = "<!--"; |
| 44 |
strClose = "-->"; |
| 45 |
strType = "comment"; |
| 46 |
} else if (strTag.indexOf("?") == 0) { |
| 47 |
strOpen = "<?"; |
| 48 |
strClose = "?>"; |
| 49 |
strType = "pi"; |
| 50 |
} else strType = "element"; |
| 51 |
if (strClose != "") { |
| 52 |
strText = ""; |
| 53 |
if (arrElementsUnparsedText[i].indexOf(strClose) > -1) strText = arrElementsUnparsedText[i]; |
| 54 |
else { |
| 55 |
for (; i<arrElementsUnparsed.length && arrElementsUnparsedText[i].indexOf(strClose) == -1; i++) { |
| 56 |
strText += arrElementsUnparsedText[i]; |
| 57 |
} |
| 58 |
strText += arrElementsUnparsedText[i]; |
| 59 |
} |
| 60 |
if (strText.substring(strOpen.length, strText.indexOf(strClose)) != "") { |
| 61 |
xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement(strType, "","",xmleLastElement,strText.substring(strOpen.length, strText.indexOf(strClose))); |
| 62 |
if (strType == "cdata") xmleLastElement.text += strText.substring(strOpen.length, strText.indexOf(strClose)); |
| 63 |
} |
| 64 |
if (strText.indexOf(strClose)+ strClose.length < strText.length) { |
| 65 |
xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement("text", "","",xmleLastElement,strText.substring(strText.indexOf(strClose)+ strClose.length, strText.length)); |
| 66 |
if (strType == "cdata") xmleLastElement.text += strText.substring(strText.indexOf(strClose)+ strClose.length, strText.length); |
| 67 |
} |
| 68 |
continue; |
| 69 |
} |
| 70 |
if (strText.replace(/ */, "") == "") strText = ""; |
| 71 |
if (arrElementsUnparsed[i].substring(1,2) != "/") { |
| 72 |
if (iElements == 0) { |
| 73 |
xmleLastElement = this.rootElement = new REXML_XMLElement(strType, strTag,strAttributes,null,strText); |
| 74 |
iElements++; |
| 75 |
if (strText != "") xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement("text", "","",xmleLastElement,strText); |
| 76 |
} else if (arrElementsUnparsed[i].substring(arrElementsUnparsed[i].length-2,arrElementsUnparsed[i].length-1) != "/") { |
| 77 |
xmleLastElement = xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement(strType, strTag,strAttributes,xmleLastElement,strText); |
| 78 |
iElements++; |
| 79 |
if (strText != "") xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement("text", "","",xmleLastElement,strText); |
| 80 |
} else { |
| 81 |
xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement(strType, strTag,strAttributes,xmleLastElement,strText); |
| 82 |
if (strText != "") xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement("text", "","",xmleLastElement,strText); |
| 83 |
} |
| 84 |
} else { |
| 85 |
xmleLastElement = xmleLastElement.parentElement; |
| 86 |
iElements--; |
| 87 |
if (xmleLastElement && strText != "") { |
| 88 |
xmleLastElement.text += strText; |
| 89 |
xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement("text", "","",xmleLastElement,strText); |
| 90 |
} |
| 91 |
} |
| 92 |
} |
| 93 |
} |
| 94 |
|
| 95 |
function REXML_XMLElement(strType, strName, strAttributes, xmlParent, strText) { |
| 96 |
this.type = strType; |
| 97 |
this.name = strName; |
| 98 |
this.attributeString = strAttributes; |
| 99 |
this.attributes = null; |
| 100 |
this.childElements = new Array(); |
| 101 |
this.parentElement = xmlParent; |
| 102 |
this.text = strText; // text of element |
| 103 |
|
| 104 |
this.getText = REXML_XMLElement_getText; // text of element and child elements |
| 105 |
this.childElement = REXML_XMLElement_childElement; |
| 106 |
this.attribute = REXML_XMLElement_attribute; |
| 107 |
} |
| 108 |
|
| 109 |
function REXML_XMLElement_getText() { |
| 110 |
if (this.type == "text" || this.type == "cdata") { |
| 111 |
return this.text; |
| 112 |
} else if (this.childElements.length) { |
| 113 |
var L = ""; |
| 114 |
for (var i=0; i<this.childElements.length; i++) { |
| 115 |
L += this.childElements[i].getText(); |
| 116 |
} |
| 117 |
return L; |
| 118 |
} else return ""; |
| 119 |
} |
| 120 |
|
| 121 |
function REXML_XMLElement_childElement(strElementName) { |
| 122 |
for (var i=0; i<this.childElements.length; i++) if (this.childElements[i].name == strElementName) return this.childElements[i]; |
| 123 |
return null; |
| 124 |
} |
| 125 |
|
| 126 |
function REXML_XMLElement_attribute(strAttributeName) { |
| 127 |
if (!this.attributes) { |
| 128 |
var reAttributes = new RegExp(" ([^= ]*)=","g"); // matches attributes |
| 129 |
if (this.attributeString.match(reAttributes) && this.attributeString.match(reAttributes).length) { |
| 130 |
var arrAttributes = this.attributeString.match(reAttributes); |
| 131 |
if (!arrAttributes.length) arrAttributes = null; |
| 132 |
else for (var j=0; j<arrAttributes.length; j++) { |
| 133 |
arrAttributes[j] = new Array( |
| 134 |
(arrAttributes[j]+"").replace(/[= ]/g,""), |
| 135 |
ParseAttribute(this.attributeString, (arrAttributes[j]+"").replace(/[= ]/g,"")) |
| 136 |
); |
| 137 |
} |
| 138 |
this.attributes = arrAttributes; |
| 139 |
} |
| 140 |
} |
| 141 |
if (this.attributes) for (var i=0; i<this.attributes.length; i++) if (this.attributes[i][0] == strAttributeName) return this.attributes[i][1]; |
| 142 |
return ""; |
| 143 |
} |
| 144 |
|
| 145 |
function ParseAttribute(str,Attribute) { |
| 146 |
var str = str + ">"; |
| 147 |
if (str.indexOf(Attribute + "='")>-1) var Attr = new RegExp(".*" + Attribute + "='([^']*)'.*>"); |
| 148 |
else if (str.indexOf(Attribute + '="')>-1) var Attr = new RegExp(".*" + Attribute + '="([^"]*)".*>'); |
| 149 |
return str.replace(Attr, "$1"); |
| 150 |
} |