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 |
} |