mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-04 17:21:39 +09:00
Apply new xml2json from XE 1.8.40
XE 1.8.40에서 업데이트된 xml2json 라이브러리를 가져와 라이믹스에 맞게 수정한다. 라이믹스에서는 exec_xml() 함수를 사용하더라도 실제로는 JSON으로 요청하므로 일부 서드파티 자료에서 XML을 반환하는 경우만 처리해 주면 된다. 평소 거의 사용하지 않는 xml2json을 기본으로 로딩하지 않고 서드파티 자료가 예기치 않게 XML을 반환했을 때만 비동기식으로 로딩하여 처리하도록 한다. 또한 xml2json이 파이어폭스에서 파싱 오류를 발생시키는 문제를 해결하기 위해 github.com/dkdndes/x2js/issues/32 패치를 적용한다.
This commit is contained in:
parent
aaaf385ce0
commit
af408a57cc
2 changed files with 608 additions and 206 deletions
575
common/js/xml2json.js
Normal file
575
common/js/xml2json.js
Normal file
|
|
@ -0,0 +1,575 @@
|
|||
/*
|
||||
Copyright 2011-2013 Abdulla Abdurakhmanov
|
||||
Original sources are available at https://code.google.com/p/x2js/
|
||||
|
||||
Licensed 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.
|
||||
*/
|
||||
|
||||
(function (root, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define([], factory);
|
||||
} else if (typeof exports === "object") {
|
||||
module.exports = factory();
|
||||
} else {
|
||||
root.X2JS = factory();
|
||||
}
|
||||
}(this, function () {
|
||||
return function (config) {
|
||||
'use strict';
|
||||
|
||||
var VERSION = "1.2.0";
|
||||
|
||||
config = config || {};
|
||||
initConfigDefaults();
|
||||
initRequiredPolyfills();
|
||||
|
||||
function initConfigDefaults() {
|
||||
if(config.escapeMode === undefined) {
|
||||
config.escapeMode = true;
|
||||
}
|
||||
|
||||
config.attributePrefix = config.attributePrefix || "_";
|
||||
config.arrayAccessForm = config.arrayAccessForm || "none";
|
||||
config.emptyNodeForm = config.emptyNodeForm || "text";
|
||||
|
||||
if(config.enableToStringFunc === undefined) {
|
||||
config.enableToStringFunc = true;
|
||||
}
|
||||
config.arrayAccessFormPaths = config.arrayAccessFormPaths || [];
|
||||
if(config.skipEmptyTextNodesForObj === undefined) {
|
||||
config.skipEmptyTextNodesForObj = true;
|
||||
}
|
||||
if(config.stripWhitespaces === undefined) {
|
||||
config.stripWhitespaces = true;
|
||||
}
|
||||
config.datetimeAccessFormPaths = config.datetimeAccessFormPaths || [];
|
||||
|
||||
if(config.useDoubleQuotes === undefined) {
|
||||
config.useDoubleQuotes = false;
|
||||
}
|
||||
|
||||
config.xmlElementsFilter = config.xmlElementsFilter || [];
|
||||
config.jsonPropertiesFilter = config.jsonPropertiesFilter || [];
|
||||
|
||||
if(config.keepCData === undefined) {
|
||||
config.keepCData = false;
|
||||
}
|
||||
}
|
||||
|
||||
var DOMNodeTypes = {
|
||||
ELEMENT_NODE : 1,
|
||||
TEXT_NODE : 3,
|
||||
CDATA_SECTION_NODE : 4,
|
||||
COMMENT_NODE : 8,
|
||||
DOCUMENT_NODE : 9
|
||||
};
|
||||
|
||||
function initRequiredPolyfills() {
|
||||
}
|
||||
|
||||
function getNodeLocalName( node ) {
|
||||
var nodeLocalName = node.localName;
|
||||
if(nodeLocalName == null) // Yeah, this is IE!!
|
||||
nodeLocalName = node.baseName;
|
||||
if(nodeLocalName == null || nodeLocalName=="") // =="" is IE too
|
||||
nodeLocalName = node.nodeName;
|
||||
return nodeLocalName;
|
||||
}
|
||||
|
||||
function getNodePrefix(node) {
|
||||
return node.prefix;
|
||||
}
|
||||
|
||||
function escapeXmlChars(str) {
|
||||
if(typeof(str) == "string")
|
||||
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
function unescapeXmlChars(str) {
|
||||
return str.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, '&');
|
||||
}
|
||||
|
||||
function checkInStdFiltersArrayForm(stdFiltersArrayForm, obj, name, path) {
|
||||
var idx = 0;
|
||||
for(; idx < stdFiltersArrayForm.length; idx++) {
|
||||
var filterPath = stdFiltersArrayForm[idx];
|
||||
if( typeof filterPath === "string" ) {
|
||||
if(filterPath == path)
|
||||
break;
|
||||
}
|
||||
else
|
||||
if( filterPath instanceof RegExp) {
|
||||
if(filterPath.test(path))
|
||||
break;
|
||||
}
|
||||
else
|
||||
if( typeof filterPath === "function") {
|
||||
if(filterPath(obj, name, path))
|
||||
break;
|
||||
}
|
||||
}
|
||||
return idx!=stdFiltersArrayForm.length;
|
||||
}
|
||||
|
||||
function toArrayAccessForm(obj, childName, path) {
|
||||
switch(config.arrayAccessForm) {
|
||||
case "property":
|
||||
if(!(obj[childName] instanceof Array))
|
||||
obj[childName+"_asArray"] = [obj[childName]];
|
||||
else
|
||||
obj[childName+"_asArray"] = obj[childName];
|
||||
break;
|
||||
/*case "none":
|
||||
break;*/
|
||||
}
|
||||
|
||||
if(!(obj[childName] instanceof Array) && config.arrayAccessFormPaths.length > 0) {
|
||||
if(checkInStdFiltersArrayForm(config.arrayAccessFormPaths, obj, childName, path)) {
|
||||
obj[childName] = [obj[childName]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fromXmlDateTime(prop) {
|
||||
// Implementation based up on http://stackoverflow.com/questions/8178598/xml-datetime-to-javascript-date-object
|
||||
// Improved to support full spec and optional parts
|
||||
var bits = prop.split(/[-T:+Z]/g);
|
||||
|
||||
var d = new Date(bits[0], bits[1]-1, bits[2]);
|
||||
var secondBits = bits[5].split("\.");
|
||||
d.setHours(bits[3], bits[4], secondBits[0]);
|
||||
if(secondBits.length>1)
|
||||
d.setMilliseconds(secondBits[1]);
|
||||
|
||||
// Get supplied time zone offset in minutes
|
||||
if(bits[6] && bits[7]) {
|
||||
var offsetMinutes = bits[6] * 60 + Number(bits[7]);
|
||||
var sign = /\d\d-\d\d:\d\d$/.test(prop)? '-' : '+';
|
||||
|
||||
// Apply the sign
|
||||
offsetMinutes = 0 + (sign == '-'? -1 * offsetMinutes : offsetMinutes);
|
||||
|
||||
// Apply offset and local timezone
|
||||
d.setMinutes(d.getMinutes() - offsetMinutes - d.getTimezoneOffset())
|
||||
}
|
||||
else
|
||||
if(prop.indexOf("Z", prop.length - 1) !== -1) {
|
||||
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()));
|
||||
}
|
||||
|
||||
// d is now a local time equivalent to the supplied time
|
||||
return d;
|
||||
}
|
||||
|
||||
function checkFromXmlDateTimePaths(value, childName, fullPath) {
|
||||
if(config.datetimeAccessFormPaths.length > 0) {
|
||||
var path = fullPath.split("\.#")[0];
|
||||
if(checkInStdFiltersArrayForm(config.datetimeAccessFormPaths, value, childName, path)) {
|
||||
return fromXmlDateTime(value);
|
||||
}
|
||||
else
|
||||
return value;
|
||||
}
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
function checkXmlElementsFilter(obj, childType, childName, childPath) {
|
||||
if( childType == DOMNodeTypes.ELEMENT_NODE && config.xmlElementsFilter.length > 0) {
|
||||
return checkInStdFiltersArrayForm(config.xmlElementsFilter, obj, childName, childPath);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
function parseDOMChildren( node, path ) {
|
||||
if(node.nodeType == DOMNodeTypes.DOCUMENT_NODE) {
|
||||
var result = new Object;
|
||||
var nodeChildren = node.childNodes;
|
||||
// Alternative for firstElementChild which is not supported in some environments
|
||||
for(var cidx=0; cidx <nodeChildren.length; cidx++) {
|
||||
var child = nodeChildren.item(cidx);
|
||||
if(child.nodeType == DOMNodeTypes.ELEMENT_NODE) {
|
||||
var childName = getNodeLocalName(child);
|
||||
result[childName] = parseDOMChildren(child, childName);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
if(node.nodeType == DOMNodeTypes.ELEMENT_NODE) {
|
||||
var result = new Object;
|
||||
result.__cnt=0;
|
||||
|
||||
var nodeChildren = node.childNodes;
|
||||
|
||||
// Children nodes
|
||||
for(var cidx=0; cidx <nodeChildren.length; cidx++) {
|
||||
var child = nodeChildren.item(cidx); // nodeChildren[cidx];
|
||||
var childName = getNodeLocalName(child);
|
||||
|
||||
if(child.nodeType!= DOMNodeTypes.COMMENT_NODE) {
|
||||
var childPath = path+"."+childName;
|
||||
if (checkXmlElementsFilter(result,child.nodeType,childName,childPath)) {
|
||||
result.__cnt++;
|
||||
if(result[childName] == null) {
|
||||
result[childName] = parseDOMChildren(child, childPath);
|
||||
toArrayAccessForm(result, childName, childPath);
|
||||
}
|
||||
else {
|
||||
if(result[childName] != null) {
|
||||
if( !(result[childName] instanceof Array)) {
|
||||
result[childName] = [result[childName]];
|
||||
toArrayAccessForm(result, childName, childPath);
|
||||
}
|
||||
}
|
||||
(result[childName])[result[childName].length] = parseDOMChildren(child, childPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attributes
|
||||
for(var aidx=0; aidx <node.attributes.length; aidx++) {
|
||||
var attr = node.attributes.item(aidx); // [aidx];
|
||||
result.__cnt++;
|
||||
result[config.attributePrefix+attr.name]=attr.value;
|
||||
}
|
||||
|
||||
// Node namespace prefix
|
||||
var nodePrefix = getNodePrefix(node);
|
||||
if(nodePrefix!=null && nodePrefix!="") {
|
||||
result.__cnt++;
|
||||
result.__prefix=nodePrefix;
|
||||
}
|
||||
|
||||
if(result["#text"]!=null) {
|
||||
result.__text = result["#text"];
|
||||
if(result.__text instanceof Array) {
|
||||
result.__text = result.__text.join("\n");
|
||||
}
|
||||
//if(config.escapeMode)
|
||||
// result.__text = unescapeXmlChars(result.__text);
|
||||
if(config.stripWhitespaces)
|
||||
result.__text = result.__text.trim();
|
||||
delete result["#text"];
|
||||
if(config.arrayAccessForm=="property")
|
||||
delete result["#text_asArray"];
|
||||
result.__text = checkFromXmlDateTimePaths(result.__text, childName, path+"."+childName);
|
||||
}
|
||||
if(result["#cdata-section"]!=null) {
|
||||
result.__cdata = result["#cdata-section"];
|
||||
delete result["#cdata-section"];
|
||||
if(config.arrayAccessForm=="property")
|
||||
delete result["#cdata-section_asArray"];
|
||||
}
|
||||
|
||||
if( result.__cnt == 0 && config.emptyNodeForm=="text" ) {
|
||||
result = '';
|
||||
}
|
||||
else
|
||||
if( result.__cnt == 1 && result.__text!=null ) {
|
||||
result = result.__text;
|
||||
}
|
||||
else
|
||||
if( result.__cnt == 1 && result.__cdata!=null && !config.keepCData ) {
|
||||
result = result.__cdata;
|
||||
}
|
||||
else
|
||||
if ( result.__cnt > 1 && result.__text!=null && config.skipEmptyTextNodesForObj) {
|
||||
if( (config.stripWhitespaces && result.__text=="") || (result.__text.trim()=="")) {
|
||||
delete result.__text;
|
||||
}
|
||||
}
|
||||
delete result.__cnt;
|
||||
|
||||
if( config.enableToStringFunc && (result.__text!=null || result.__cdata!=null )) {
|
||||
result.toString = function() {
|
||||
return (this.__text!=null? this.__text:'')+( this.__cdata!=null ? this.__cdata:'');
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
if(node.nodeType == DOMNodeTypes.TEXT_NODE || node.nodeType == DOMNodeTypes.CDATA_SECTION_NODE) {
|
||||
return node.nodeValue;
|
||||
}
|
||||
}
|
||||
|
||||
function startTag(jsonObj, element, attrList, closed) {
|
||||
var resultStr = "<"+ ( (jsonObj!=null && jsonObj.__prefix!=null)? (jsonObj.__prefix+":"):"") + element;
|
||||
if(attrList!=null) {
|
||||
for(var aidx = 0; aidx < attrList.length; aidx++) {
|
||||
var attrName = attrList[aidx];
|
||||
var attrVal = jsonObj[attrName];
|
||||
if(config.escapeMode)
|
||||
attrVal=escapeXmlChars(attrVal);
|
||||
resultStr+=" "+attrName.substr(config.attributePrefix.length)+"=";
|
||||
if(config.useDoubleQuotes)
|
||||
resultStr+='"'+attrVal+'"';
|
||||
else
|
||||
resultStr+="'"+attrVal+"'";
|
||||
}
|
||||
}
|
||||
if(!closed)
|
||||
resultStr+=">";
|
||||
else
|
||||
resultStr+="/>";
|
||||
return resultStr;
|
||||
}
|
||||
|
||||
function endTag(jsonObj,elementName) {
|
||||
return "</"+ (jsonObj.__prefix!=null? (jsonObj.__prefix+":"):"")+elementName+">";
|
||||
}
|
||||
|
||||
function endsWith(str, suffix) {
|
||||
return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
||||
}
|
||||
|
||||
function jsonXmlSpecialElem ( jsonObj, jsonObjField ) {
|
||||
if((config.arrayAccessForm=="property" && endsWith(jsonObjField.toString(),("_asArray")))
|
||||
|| jsonObjField.toString().indexOf(config.attributePrefix)==0
|
||||
|| jsonObjField.toString().indexOf("__")==0
|
||||
|| (jsonObj[jsonObjField] instanceof Function) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function jsonXmlElemCount ( jsonObj ) {
|
||||
var elementsCnt = 0;
|
||||
if(jsonObj instanceof Object ) {
|
||||
for( var it in jsonObj ) {
|
||||
if(jsonXmlSpecialElem ( jsonObj, it) )
|
||||
continue;
|
||||
elementsCnt++;
|
||||
}
|
||||
}
|
||||
return elementsCnt;
|
||||
}
|
||||
|
||||
function checkJsonObjPropertiesFilter(jsonObj, propertyName, jsonObjPath) {
|
||||
return config.jsonPropertiesFilter.length == 0
|
||||
|| jsonObjPath==""
|
||||
|| checkInStdFiltersArrayForm(config.jsonPropertiesFilter, jsonObj, propertyName, jsonObjPath);
|
||||
}
|
||||
|
||||
function parseJSONAttributes ( jsonObj ) {
|
||||
var attrList = [];
|
||||
if(jsonObj instanceof Object ) {
|
||||
for( var ait in jsonObj ) {
|
||||
if(ait.toString().indexOf("__")== -1 && ait.toString().indexOf(config.attributePrefix)==0) {
|
||||
attrList.push(ait);
|
||||
}
|
||||
}
|
||||
}
|
||||
return attrList;
|
||||
}
|
||||
|
||||
function parseJSONTextAttrs ( jsonTxtObj ) {
|
||||
var result ="";
|
||||
|
||||
if(jsonTxtObj.__cdata!=null) {
|
||||
result+="<![CDATA["+jsonTxtObj.__cdata+"]]>";
|
||||
}
|
||||
|
||||
if(jsonTxtObj.__text!=null) {
|
||||
if(config.escapeMode)
|
||||
result+=escapeXmlChars(jsonTxtObj.__text);
|
||||
else
|
||||
result+=jsonTxtObj.__text;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseJSONTextObject ( jsonTxtObj ) {
|
||||
var result ="";
|
||||
|
||||
if( jsonTxtObj instanceof Object ) {
|
||||
result+=parseJSONTextAttrs ( jsonTxtObj );
|
||||
}
|
||||
else
|
||||
if(jsonTxtObj!=null) {
|
||||
if(config.escapeMode)
|
||||
result+=escapeXmlChars(jsonTxtObj);
|
||||
else
|
||||
result+=jsonTxtObj;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getJsonPropertyPath(jsonObjPath, jsonPropName) {
|
||||
if (jsonObjPath==="") {
|
||||
return jsonPropName;
|
||||
}
|
||||
else
|
||||
return jsonObjPath+"."+jsonPropName;
|
||||
}
|
||||
|
||||
function parseJSONArray ( jsonArrRoot, jsonArrObj, attrList, jsonObjPath ) {
|
||||
var result = "";
|
||||
if(jsonArrRoot.length == 0) {
|
||||
result+=startTag(jsonArrRoot, jsonArrObj, attrList, true);
|
||||
}
|
||||
else {
|
||||
for(var arIdx = 0; arIdx < jsonArrRoot.length; arIdx++) {
|
||||
result+=startTag(jsonArrRoot[arIdx], jsonArrObj, parseJSONAttributes(jsonArrRoot[arIdx]), false);
|
||||
result+=parseJSONObject(jsonArrRoot[arIdx], getJsonPropertyPath(jsonObjPath,jsonArrObj));
|
||||
result+=endTag(jsonArrRoot[arIdx],jsonArrObj);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseJSONObject ( jsonObj, jsonObjPath ) {
|
||||
var result = "";
|
||||
|
||||
var elementsCnt = jsonXmlElemCount ( jsonObj );
|
||||
|
||||
if(elementsCnt > 0) {
|
||||
for( var it in jsonObj ) {
|
||||
|
||||
if(jsonXmlSpecialElem ( jsonObj, it) || (jsonObjPath!="" && !checkJsonObjPropertiesFilter(jsonObj, it, getJsonPropertyPath(jsonObjPath,it))) )
|
||||
continue;
|
||||
|
||||
var subObj = jsonObj[it];
|
||||
|
||||
var attrList = parseJSONAttributes( subObj )
|
||||
|
||||
if(subObj == null || subObj == undefined) {
|
||||
result+=startTag(subObj, it, attrList, true);
|
||||
}
|
||||
else
|
||||
if(subObj instanceof Object) {
|
||||
|
||||
if(subObj instanceof Array) {
|
||||
result+=parseJSONArray( subObj, it, attrList, jsonObjPath );
|
||||
}
|
||||
else if(subObj instanceof Date) {
|
||||
result+=startTag(subObj, it, attrList, false);
|
||||
result+=subObj.toISOString();
|
||||
result+=endTag(subObj,it);
|
||||
}
|
||||
else {
|
||||
var subObjElementsCnt = jsonXmlElemCount ( subObj );
|
||||
if(subObjElementsCnt > 0 || subObj.__text!=null || subObj.__cdata!=null) {
|
||||
result+=startTag(subObj, it, attrList, false);
|
||||
result+=parseJSONObject(subObj, getJsonPropertyPath(jsonObjPath,it));
|
||||
result+=endTag(subObj,it);
|
||||
}
|
||||
else {
|
||||
result+=startTag(subObj, it, attrList, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
result+=startTag(subObj, it, attrList, false);
|
||||
result+=parseJSONTextObject(subObj);
|
||||
result+=endTag(subObj,it);
|
||||
}
|
||||
}
|
||||
}
|
||||
result+=parseJSONTextObject(jsonObj);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
this.parseXmlString = function(xmlDocStr) {
|
||||
var isIEParser = window.ActiveXObject || "ActiveXObject" in window;
|
||||
if (xmlDocStr === undefined) {
|
||||
return null;
|
||||
}
|
||||
var xmlDoc;
|
||||
if (window.DOMParser) {
|
||||
var parser=new window.DOMParser();
|
||||
try {
|
||||
xmlDoc = parser.parseFromString( xmlDocStr, "text/xml" );
|
||||
if(xmlDoc.getElementsByTagNameNS('*', "parsererror").length > 0) {
|
||||
//throw new Error('Error parsing XML: '+xmlDocStr);
|
||||
xmlDoc = null;
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
xmlDoc = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// IE :(
|
||||
if(xmlDocStr.indexOf("<?")==0) {
|
||||
xmlDocStr = xmlDocStr.substr( xmlDocStr.indexOf("?>") + 2 );
|
||||
}
|
||||
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
|
||||
xmlDoc.async="false";
|
||||
xmlDoc.loadXML(xmlDocStr);
|
||||
}
|
||||
return xmlDoc;
|
||||
};
|
||||
|
||||
this.asArray = function(prop) {
|
||||
if (prop === undefined || prop == null)
|
||||
return [];
|
||||
else
|
||||
if(prop instanceof Array)
|
||||
return prop;
|
||||
else
|
||||
return [prop];
|
||||
};
|
||||
|
||||
this.toXmlDateTime = function(dt) {
|
||||
if(dt instanceof Date)
|
||||
return dt.toISOString();
|
||||
else
|
||||
if(typeof(dt) === 'number' )
|
||||
return new Date(dt).toISOString();
|
||||
else
|
||||
return null;
|
||||
};
|
||||
|
||||
this.asDateTime = function(prop) {
|
||||
if(typeof(prop) == "string") {
|
||||
return fromXmlDateTime(prop);
|
||||
}
|
||||
else
|
||||
return prop;
|
||||
};
|
||||
|
||||
this.xml2json = function (xmlDoc) {
|
||||
return parseDOMChildren ( xmlDoc );
|
||||
};
|
||||
|
||||
this.xml_str2json = function (xmlDocStr) {
|
||||
var xmlDoc = this.parseXmlString(xmlDocStr);
|
||||
if(xmlDoc!=null)
|
||||
return this.xml2json(xmlDoc);
|
||||
else
|
||||
return null;
|
||||
};
|
||||
|
||||
this.json2xml_str = function (jsonObj) {
|
||||
return parseJSONObject ( jsonObj, "" );
|
||||
};
|
||||
|
||||
this.json2xml = function (jsonObj) {
|
||||
var xmlDocStr = this.json2xml_str (jsonObj);
|
||||
return this.parseXmlString(xmlDocStr);
|
||||
};
|
||||
|
||||
this.getVersion = function () {
|
||||
return VERSION;
|
||||
};
|
||||
}
|
||||
}))
|
||||
|
|
@ -23,6 +23,9 @@
|
|||
*/
|
||||
window.exec_xml = $.exec_xml = function(module, act, params, callback_success, return_fields, callback_success_arg, fo_obj) {
|
||||
|
||||
// Define callback functions.
|
||||
var successHandler, errorHandler, xmlHandler;
|
||||
|
||||
// Convert params to object and fill in the module and act.
|
||||
params = params ? ($.isArray(params) ? arr2obj(params) : params) : {};
|
||||
params.module = module;
|
||||
|
|
@ -58,7 +61,7 @@
|
|||
}, 1000);
|
||||
|
||||
// Define the success handler.
|
||||
var successHandler = function(data, textStatus, xhr) {
|
||||
successHandler = function(data, textStatus, xhr) {
|
||||
|
||||
// Hide the waiting message.
|
||||
clearTimeout(wfsr_timeout);
|
||||
|
|
@ -115,17 +118,11 @@
|
|||
};
|
||||
|
||||
// Define the error handler.
|
||||
var errorHandler = function(xhr, textStatus) {
|
||||
errorHandler = function(xhr, textStatus, doNotHandleXml) {
|
||||
|
||||
// If the server has returned XML anyway, convert to JSON and call the success handler.
|
||||
if (textStatus === 'parsererror' && xhr.responseText && xhr.responseText.match(/<response/)) {
|
||||
var xmldata = $.parseXML(xhr.responseText);
|
||||
if (xmldata) {
|
||||
var jsondata = $.parseJSON(xml2json(xmldata, false, false));
|
||||
if (jsondata && jsondata.response) {
|
||||
return successHandler(jsondata.response, textStatus, xhr);
|
||||
}
|
||||
}
|
||||
if (textStatus === 'parsererror' && doNotHandleXml !== true && xhr.responseText && xhr.responseText.match(/<response/)) {
|
||||
return xmlHandler(xhr, textStatus);
|
||||
}
|
||||
|
||||
// Hide the waiting message and display an error notice.
|
||||
|
|
@ -142,6 +139,32 @@
|
|||
}
|
||||
};
|
||||
|
||||
// Define the legacy XML handler.
|
||||
xmlHandler = function(xhr, textStatus) {
|
||||
var parseXmlAndReturn = function() {
|
||||
var x2js = new X2JS();
|
||||
var data = x2js.xml_str2json($.trim(xhr.responseText));
|
||||
if (data && data.response) {
|
||||
return successHandler(data.response, textStatus, xhr);
|
||||
} else {
|
||||
return errorHandler(xhr, textStatus, true);
|
||||
}
|
||||
};
|
||||
if (window.X2JS) {
|
||||
parseXmlAndReturn();
|
||||
} else {
|
||||
$.ajax({
|
||||
url : request_uri + "common/js/xml2json.js",
|
||||
dataType : "script",
|
||||
cache : true,
|
||||
success : parseXmlAndReturn,
|
||||
error : function() {
|
||||
return errorHandler(xhr, textStatus, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Send the AJAX request.
|
||||
try {
|
||||
$.ajax({
|
||||
|
|
@ -407,199 +430,3 @@ function arr2obj(arr) {
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* This work is licensed under Creative Commons GNU LGPL License.
|
||||
* License: http://creativecommons.org/licenses/LGPL/2.1/
|
||||
* Version: 0.9
|
||||
* Author: Stefan Goessner/2006
|
||||
* Web: http://goessner.net/
|
||||
**/
|
||||
function xml2json(xml, tab, ignoreAttrib) {
|
||||
var X = {
|
||||
toObj: function(xml) {
|
||||
var o = {};
|
||||
if (xml.nodeType==1) { // element node ..
|
||||
if (ignoreAttrib && xml.attributes.length) { // element with attributes ..
|
||||
for (var i=0; i<xml.attributes.length; i++) {
|
||||
o["@"+xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue||"").toString();
|
||||
}
|
||||
}
|
||||
|
||||
if (xml.firstChild) { // element has child nodes ..
|
||||
var textChild=0, cdataChild=0, hasElementChild=false;
|
||||
for (var n=xml.firstChild; n; n=n.nextSibling) {
|
||||
if (n.nodeType==1) {
|
||||
hasElementChild = true;
|
||||
} else if (n.nodeType==3 && n.nodeValue.match(/[^ \f\n\r\t\v]/)) {
|
||||
textChild++; // non-whitespace text
|
||||
}else if (n.nodeType==4) {
|
||||
cdataChild++; // cdata section node
|
||||
}
|
||||
}
|
||||
if (hasElementChild) {
|
||||
if (textChild < 2 && cdataChild < 2) { // structured element with evtl. a single text or/and cdata node ..
|
||||
X.removeWhite(xml);
|
||||
for (var n1=xml.firstChild; n1; n1=n1.nextSibling) {
|
||||
if (n1.nodeType == 3) { // text node
|
||||
o = X.unescape(X.escape(n1.nodeValue));
|
||||
} else if (n1.nodeType == 4) { // cdata node
|
||||
// o["#cdata"] = X.escape(n.nodeValue);
|
||||
o = X.escape(n1.nodeValue);
|
||||
} else if (o[n1.nodeName]) { // multiple occurence of element ..
|
||||
if (o[n1.nodeName] instanceof Array) {
|
||||
o[n1.nodeName][o[n1.nodeName].length] = X.toObj(n1);
|
||||
} else {
|
||||
o[n1.nodeName] = [o[n1.nodeName], X.toObj(n1)];
|
||||
}
|
||||
} else { // first occurence of element..
|
||||
o[n1.nodeName] = X.toObj(n1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // mixed content
|
||||
if (!xml.attributes.length) {
|
||||
o = X.unescape(X.escape(X.innerXml(xml)));
|
||||
} else {
|
||||
o["#text"] = X.unescape(X.escape(X.innerXml(xml)));
|
||||
}
|
||||
}
|
||||
} else if (textChild) { // pure text
|
||||
if (!xml.attributes.length) {
|
||||
o = X.unescape(X.escape(X.innerXml(xml)));
|
||||
} else {
|
||||
o["#text"] = X.unescape(X.escape(X.innerXml(xml)));
|
||||
}
|
||||
} else if (cdataChild) { // cdata
|
||||
if (cdataChild > 1) {
|
||||
o = X.escape(X.innerXml(xml));
|
||||
} else {
|
||||
for (var n2=xml.firstChild; n2; n2=n2.nextSibling) {
|
||||
// o["#cdata"] = X.escape(n2.nodeValue);
|
||||
o = X.escape(n2.nodeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!xml.attributes.length && !xml.firstChild) {
|
||||
o = null;
|
||||
}
|
||||
} else if (xml.nodeType==9) { // document.node
|
||||
o = X.toObj(xml.documentElement);
|
||||
} else {
|
||||
alert("unhandled node type: " + xml.nodeType);
|
||||
}
|
||||
|
||||
return o;
|
||||
},
|
||||
toJson: function(o, name, ind) {
|
||||
var json = name ? ("\""+name+"\"") : "";
|
||||
if (o instanceof Array) {
|
||||
for (var i=0,n=o.length; i<n; i++) {
|
||||
o[i] = X.toJson(o[i], "", ind+"\t");
|
||||
}
|
||||
json += (name?":[":"[") + (o.length > 1 ? ("\n"+ind+"\t"+o.join(",\n"+ind+"\t")+"\n"+ind) : o.join("")) + "]";
|
||||
} else if (o === null) {
|
||||
json += (name&&":") + "null";
|
||||
} else if (typeof(o) == "object") {
|
||||
var arr = [];
|
||||
for (var m in o) {
|
||||
arr[arr.length] = X.toJson(o[m], m, ind+"\t");
|
||||
}
|
||||
json += (name?":{":"{") + (arr.length > 1 ? ("\n"+ind+"\t"+arr.join(",\n"+ind+"\t")+"\n"+ind) : arr.join("")) + "}";
|
||||
} else if (typeof(o) == "string") {
|
||||
json += (name&&":") + "\"" + o.toString() + "\"";
|
||||
} else {
|
||||
json += (name&&":") + o.toString();
|
||||
}
|
||||
return json;
|
||||
},
|
||||
innerXml: function(node) {
|
||||
var s = "";
|
||||
|
||||
if ("innerHTML" in node) {
|
||||
s = node.innerHTML;
|
||||
} else {
|
||||
var asXml = function(n) {
|
||||
var s = "";
|
||||
if (n.nodeType == 1) {
|
||||
s += "<" + n.nodeName;
|
||||
for (var i=0; i<n.attributes.length;i++) {
|
||||
s += " " + n.attributes[i].nodeName + "=\"" + (n.attributes[i].nodeValue||"").toString() + "\"";
|
||||
}
|
||||
if (n.firstChild) {
|
||||
s += ">";
|
||||
for (var c=n.firstChild; c; c=c.nextSibling) {
|
||||
s += asXml(c);
|
||||
}
|
||||
s += "</"+n.nodeName+">";
|
||||
} else {
|
||||
s += "/>";
|
||||
}
|
||||
} else if (n.nodeType == 3) {
|
||||
s += n.nodeValue;
|
||||
} else if (n.nodeType == 4) {
|
||||
s += "<![CDATA[" + n.nodeValue + "]]>";
|
||||
}
|
||||
|
||||
return s;
|
||||
};
|
||||
|
||||
for (var c=node.firstChild; c; c=c.nextSibling) {
|
||||
s += asXml(c);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
},
|
||||
escape: function(txt) {
|
||||
return txt.replace(/[\\]/g, "\\\\")
|
||||
.replace(/[\"]/g, '\\"')
|
||||
.replace(/[\n]/g, '\\n')
|
||||
.replace(/[\r]/g, '\\r');
|
||||
},
|
||||
unescape: function(txt) {
|
||||
if (!navigator.userAgent.match(/Trident\/7.0/)) {
|
||||
return txt.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
||||
} else {
|
||||
return txt;
|
||||
}
|
||||
},
|
||||
removeWhite: function(e) {
|
||||
e.normalize();
|
||||
for (var n3 = e.firstChild; n3; ) {
|
||||
if (n3.nodeType == 3) { // text node
|
||||
if (!n3.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node
|
||||
var nxt = n3.nextSibling;
|
||||
e.removeChild(n3);
|
||||
n3 = nxt;
|
||||
} else {
|
||||
n3 = n3.nextSibling;
|
||||
}
|
||||
} else if (n3.nodeType == 1) { // element node
|
||||
X.removeWhite(n3);
|
||||
n3 = n3.nextSibling;
|
||||
} else { // any other node
|
||||
n3 = n3.nextSibling;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
// document node
|
||||
if (xml.nodeType == 9) xml = xml.documentElement;
|
||||
|
||||
var json_obj = X.toObj(X.removeWhite(xml)), json_str;
|
||||
|
||||
if (typeof(JSON)=='object' && jQuery.isFunction(JSON.stringify) && false) {
|
||||
var obj = {}; obj[xml.nodeName] = json_obj;
|
||||
json_str = JSON.stringify(obj);
|
||||
|
||||
return json_str;
|
||||
} else {
|
||||
json_str = X.toJson(json_obj, xml.nodeName, "");
|
||||
|
||||
return "{" + (tab ? json_str.replace(/\t/g, tab) : json_str.replace(/\t|\n/g, "")) + "}";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue