📄 xmlserialize.js
字号:
/*
* Isomorphic SmartClient
* Version 6.5 (2008-04-30)
* Copyright(c) 1998-2007 Isomorphic Software, Inc. All rights reserved.
* "SmartClient" is a trademark of Isomorphic Software, Inc.
*
* licensing@smartclient.com
*
* http://smartclient.com/license
*/
////= @object XMLSerialize//// xml serialize() methods for the comm package//// XXX this package must not be dependant on the Comm package, because serialization is a useful// feature completely apart from Comm. Unfortunately, the methods are currently expected to be on// the Comm class, so if the Comm class doesn't exist we need to define it.if (!isc.Comm) isc.defineClass("Comm");isc.Comm.addClassProperties( { // prefixes for special object types //> @classAttr Comm.XML_BACKREF_PREFIX (String : "$$BACKREF$$:" : IR) // @group serialization // Prefix for back-references in serialized object references. //< XML_BACKREF_PREFIX : "$$BACKREF$$:", _xmlIdentifierRegex : /^([_:A-Za-z])([_:.A-Za-z0-9]|-)*$/});isc.Comm.addClassMethods( {//> @classMethod Comm.xmlSerialize()// Serialize an object of any type into an xml string, in a form that// can be read by server-side code via schemaless transform//// Note: You should call this routine to serialize any type of object,// rather than calling the custom routines on that object...// // @group xml serialization// @param name (any) name of object to be serialized (used for outer XML tag)// @param object (any) object to be serialized// @param [indent] (boolean) true == output should be indented for reading, // false == no indentation//// @return (string) serialization form of the object//<xmlSerialize : function (name, object, indent, removeFields, keepFields) { return isc.Comm._xmlSerialize(name, object, indent ? "" : null, removeFields, keepFields);},//> @classMethod Comm._xmlSerialize() (IA)// Internal routine that actually does the serialization.// @group serialization//// @param name (string) name of the object for XML tags// @param object (any) object to serialize// @param prefix (string) string to put before each line of serialization output// @param context (object) context tracking objects already serialized and path// traversed so far//// @return (string) serialized object as a string//<_xmlSerialize : function (name, object, prefix, context, removeFields, keepFields) { // record whether a name was explicitly passed var namePassed = name != null; // NOTE: allow context as a partial object, so eg isRoot can be set if (!context || !context.objRefs) { context = isc.addProperties({}, context); context.objRefs = {obj:[],path:[]}; if (!context.objPath) { if (object && object.getID) context.objPath = object.getID(); else context.objPath = ""; } if (name == null) { if (isc.isA.Class(object)) name = object.getClassName(); else if (isc.isAn.Array(object)) name = "Array"; else if (isc.isA.Object(object)) name = object.$schemaId || "Object"; else name = "ISC_Auto"; } } // handle simple types // NOTE: must be able to send null, which potentially has a distinct meaning to the // backend (eg nulling out a text field vs setting to empty string). Null is encoded // distinctly from empty string by simply omitting the explicit typing to String. if (object == null) return isc.Comm._xmlValue(name, ""); if (isc.isA.String(object)) { return isc.Comm._xmlValue(name, isc.makeXMLSafe(object), (isc.Comm.xmlSchemaMode ? "string" : null)); } if (isc.isA.Function(object)) { if (object.iscAction) return isc.StringMethod._xmlSerializeAction(object.iscAction); return null; } if (object == window) { this.logWarn("Serializer encountered the window object at path: " + context.objPath +" - returning null for this slot."); return null; } // XML comm supports strong typing of numbers and booleans, but JS comm does not (the type // information is not propagated). Preserving the type is useful, so we default to that - but // this can be disabled if (isc.RPCManager.preserveTypes) { // for numbers, distinguish between float and integer // NOTE: special numbers like NaN and Infinity aren't allowed in the XML Schema numeric // types - the XML schema approach here would be to declare a union type between a // numeric base type and an enum of NaN, Infinity, etc. if (isc.isA.Number(object) || isc.isA.SpecialNumber(object)) { if (object.toString().contains(".")) return isc.Comm._xmlValue(name, object, "double"); return isc.Comm._xmlValue(name, object, "long"); } if (isc.isA.Boolean(object)) return isc.Comm._xmlValue(name, object, "boolean"); } else { // old approach if (isc.isA.Number(object) || isNaN(object)) { return isc.Comm._xmlValue(name, object); } if (isc.isA.Boolean(object)) return isc.Comm._xmlValue(name, object); } // for complex types: // detect infinite loops by checking if we've seen this object before. // disambiguate between true loops vs the same leaf object being encountered twice // (such as a simple Array containing two Strings which appears in two spots). Only // consider this a loop if the preceding occurence of the object was some parent of // ours. var prevPath = isc.Comm._serialize_alreadyReferenced(context.objRefs, object); if (prevPath != null && context.objPath.contains(prevPath)) { // Note: check that the first char after "prevPath" is a path separator char in order // to avoid false loop detection with "prop" and "prop2" having the same non-looping // object (since "prop2" contains "prop"). var nextChar = context.objPath.substring(prevPath.length, prevPath.length+1); //this.logWarn("backref: prevPath: " + prevPath + ", current: " + context.objPath + // ", char after prevPath: " + nextChar); if (nextChar == "." || nextChar == "[" || nextChar == "]") { if (this.serializeBackrefs) { return isc.Comm._xmlOpenTag(name) + isc.Comm.XML_BACKREF_PREFIX + prevPath + isc.Comm._xmlCloseTag(name); } return isc.emptyString; } } // remember Objects and Arrays to avoid infinite loops isc.Comm._serialize_remember(context.objRefs, object, context.objPath); // if there is an xmlSerialize method associated with this object, call that if (isc.isA.Function(object._xmlSerialize)) { return object._xmlSerialize(name, null, null, prefix, context.objRefs, context.objPath); } else if (isc.isA.Class(object)) { this.logWarn("Attempt to serialize class of type: " + object.getClassName() + " at path: " + context.objPath + " - returning null for this slot."); return null; } // we define the xsi namespace on the first nested object that we encounter. The first such // object sets the value isRoot on the context to 'false' explicitly. If it's not defined, then // it's true. var isRoot = context.isRoot == false ? false : true; // handle arrays as a special case if (isc.isAn.Array(object)) return isc.Comm._xmlSerializeArray(name, object, context.objPath, context.objRefs, prefix, isRoot); if (!removeFields) removeFields = []; if (!keepFields) keepFields = []; // and return anything else as a simple object - if the object has a getSerializeableFields // method on it - use that otherwise just use the object var serializeableFields = object.getSerializeableFields ? object.getSerializeableFields(removeFields, keepFields) : object; return isc.Comm._xmlSerializeObject(name, serializeableFields, context.objPath, context.objRefs, prefix, isRoot);},//> @classMethod Comm._xmlSerializeArray() (A)// Internal routine to serialize an array.//// @group serialization// @param name (string) name of the object for XML tags// @param object (any) object to serialize// @param prefix (string) string to put before each line of serialization output// @param objRefs (object[]) array of objects that have been serialized already so// we don't get into endless loops // @param objPath (string) global variable path to this object, for serializing object references//// @return (string) serialized object as a string//<_xmlSerializeArray : function (name, object, objPath, objRefs, prefix, isRoot) { // open xml tag var result = isc.Comm._xmlOpenTag(name, "List", null, null, null, isRoot); // spin through the array and create <elem>value</elem> strings for (var i = 0, len = object.length; i < len; i++) { var value = object[i]; var context = { objRefs : objRefs, objPath : isc.Comm._serialize_addToPath(objPath, i), isRoot : false
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -