📄 xmltools.js
字号:
} if (this.logIsDebugEnabled(this._$xmlToJS)) { this.logDebug("simpleType field: " + this.echoLeaf(field) + " got value: " + this.echoLeaf(childValue), "xmlToJS"); } } } if (field && field.multiple) { // null or the empty string, the result of a nil or empty element // respectively, should be considered an empty array for a multiple field if (childValue == null || isc.isA.emptyString(childValue)) childValue = []; // anything else should be wrapped in an Array if it's singular else if (!isc.isAn.Array(childValue)) childValue = [childValue]; } // collision on the tagName - make an array if (object[childName]) { if (!isc.isAn.Array(object[childName])) object[childName] = [object[childName]]; if (field && field.multiple && isc.isAn.Array(childValue)) { // for "multiple" fields, avoid nested Arrays object[childName].addList(childValue); } else { object[childName].add(childValue); } } else { object[childName] = childValue; } } // for an element that has no element children, store it's textContent, if any, as a // special property. Note that we still drop text content around element children, but // this is typically either whitespace/CRs used for formatting, or the relative order of // the text and subelements matters and hence a very different representation would be // needed. if (!hadElementChildren) { var textContent = this.getElementText(element), prop = context.textContentProperty || (dataSource ? dataSource.textContentProperty : "xmlTextContent"); // if there's a field definition for textContent, validate against it if (dataSource) { field = dataSource.getTextContentField(); //this.logWarn("validating against textContentField: " + this.echoLeaf(field) + // ", with validators: " + this.echoAll(field.validators)); if (field) textContent = dataSource.validateFieldValue(field, textContent); } if (textContent != null && !isc.isAn.emptyString(textContent)) { object[prop] = textContent; } } // if we have a dataSource with a instanceConstructor property that maps to an existing // class, create a new one of those with the data we've mined off the XML if (dataSource && (dataSource.instanceConstructor || dataSource.Constructor)) { var Constructor = dataSource.instanceConstructor || dataSource.Constructor; //this.logWarn("toJS creating an instance of: " + Constructor + // " with properties: " + isc.echo(object)); if (context != null && context.propertiesOnly) { object._constructor = Constructor; } else if (isc.ClassFactory.getClass(Constructor) != null) { return isc.ClassFactory.newInstance(Constructor, object); } } return object;},// copied from BasicDataSource.getExplicitType() in server code_$type : "type",_$xsiType : "xsi:type",getExplicitType : function (element) { if (element == null || this.isTextNode(element)) return; var type = this.getXSIAttribute(element, this._$type); if (type) { if (type.contains(isc.colon)) type = type.substring(type.indexOf(isc.colon)+1); return type; } type = element.getAttribute("constructor"); return type;},// converts isomorphic:XML to components, complains about missing system schematoComponents : function (xmlDoc, context) { if (isc.DS.get("Canvas") == null) { this.logWarn("Can't find schema for Canvas - make sure you've loaded" +" component schema via <isomorphic:loadSystemSchema/> jsp tag" +" or by some other mechanism"); } // accept string or xml document if (isc.isA.String(xmlDoc)) { // accept non-well-formed documents that are just a bunch of ISC components with no // containing <isomorphicXML> tag by wrapping the components in an <isomorphicXML> tag // if initial parse run fails var doc = this.parseXML(xmlDoc, true); if (doc.hasParseError()) { this.logWarn("xml failed to parse xmlDoc, wrapping in root node."); doc = this.parseXML("<isomorphicXML>"+xmlDoc+"</isomorphicXML>"); } xmlDoc = doc; } return this.toJS(xmlDoc, null, null, true, context);},_$number : "number", getFieldValue : function (record, fieldName, field, dataSource, namespaces) { if (record.ownerDocument == null) return record[fieldName]; // if a field is passed, it's from a UI component, and is the complete field definition // whether the UI component was databound or not because databound components merge their // fields against dataSource fields field = field || (dataSource ? dataSource.getField(fieldName) : isc.emptyObject); try { var value; if (field.valueXPath) { // if the field is of DataSource type, use the valueXPath to select nodes (not a // scalar value), and do recursive transform on those elements var fieldDS = (dataSource ? dataSource.getSchema(field.type) : isc.DS.get(field.type)); if (fieldDS) { var elements = isc.xml.selectNodes(record, field.valueXPath, namespaces), records = isc.xml.toJS(elements, null, fieldDS); // selectNodes always returns an Array, but we only want an Array value if the // field is declared multiple or if multiple nodes really did match. if (!field.multiple && records.length == 1) records = records[0]; return records; } else { // otherwise simple scalar value value = isc.xml.selectScalar(record, field.valueXPath, namespaces); } } else { value = isc.xml.getXMLFieldValue(record, fieldName); } // the value retrieved from XML is always just a string, so we need to convert it // to the proper type. NOTE: call instance method to allow overrides. dataSource = dataSource || isc.DS.get("Object"); value = dataSource.validateFieldValue(field, value); //this.logWarn("At field: " + dataSource.ID + "." + field.name + // " got value: " + this.echoLeaf(value)); return value; } catch (e) { this.logWarn("error getting value for field: '" + fieldName + (field.valueXPath ? "', valueXPath: '" + field.valueXPath : "") + "' in record: " + this.echo(record) + "\r: " + this.echo(e) + this.getStackTrace()); return null; }},// given an XML element, get the value for the given fieldName by checking attributes, then// subelements. Returned value is always a String or null.getXMLFieldValue : function (element, fieldName) { // attribute representation var attrValue = element.getAttribute(fieldName); if (attrValue != null) return attrValue; // subElement representation // NOTE: a tagName of "record" matches <foo:record> in Moz, but NOT in IE var subElement = element.getElementsByTagName(fieldName)[0]; if (subElement == null) return null; return (isc.Browser.isIE ? subElement.text : subElement.textContent);},// whether the element has any attributes that should be considered data, as opposed to// encoding directives like "xsi:type"_hasDataAttributes : function (attributes) { for (var attrName in attributes) { if (attrName == this._$xsiType) continue; return true; } return false;},getAttributes : function (element, attrMask, object, dontClobber, dataSource) { // NOTE: hasAttributes() doesn't exist in IE // optionally add to existing object object = object || {}; var undef; // look up the attributes specified by attrMask if (attrMask) { if (!isc.isAn.Array(attrMask)) attrMask = [attrMask]; for (var i = 0; i < attrMask.length; i++) { var attrName = attrMask[i]; if (dontClobber && object[attrName] !== undef) continue; var attrValue = element.getAttribute(attrName); if (attrValue == null || isc.isAn.emptyString(attrValue)) continue; if (dataSource && dataSource.getField(attrName)) { attrValue = dataSource.validateFieldValue(dataSource.getField(attrName), attrValue); } object[attrName] = attrValue; } return object; } // tranform attributes to properties var attrs = element.attributes; if (attrs != null) { for (var i = 0; i < attrs.length; i++) { var attr = attrs[i], attrName = attr.name; if (dontClobber && object[attrName] !== undef) continue; var attrValue = attr.value; if (attrValue == null || isc.isAn.emptyString(attrValue)) continue; if (dataSource && dataSource.getField(attrName)) { attrValue = dataSource.validateFieldValue(dataSource.getField(attrName), attrValue); } object[attrName] = attrValue; } } return object;},_$xsi : { nil : "xsi:nil", "null" : "xsi:null", type : "xsi:type"},xsiNamespaces : [ "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/1999/XMLSchema-instance"],getXSIAttribute : function (element, attrName) { var value; // Opera requires that we call getAttributeNS to get the xsi elements, using e.g: // getAttribute("xsi:type") returns null, even if set. Probably should use this code // with other browser as well, but it's slower (because we have to try all the // xsiNamespaces) and untested on other platforms. if (isc.Browser.isOpera) { for (var i = 0; i < this.xsiNamespaces.length; i++) { value = element.getAttributeNS(this.xsiNamespaces[i], attrName); if (value != null) return value; } return value; } return element.getAttribute(this._$xsi[attrName]);},_$nil : "nil",_$null : "null",_$false : "false",_$zero : "0",elementIsNil : function (element) { if (element == null || !isc.isA.XMLNode(element) || element.nodeType != 1) return false; var nilAttribute = this.getXSIAttribute(element, this._$nil); if (nilAttribute && nilAttribute != this._$false && nilAttribute != this._$zero) return true; var nilAttribute = this.getXSIAttribute(element, this._$null); if (nilAttribute && nilAttribute != this._$false && nilAttribute != this._$zero) return true; return false;},getElementText : function (element) { if (this.elementIsNil(element)) return null; if (!element) return null; var child = element.firstChild; if (!child) return isc.emptyString; // empty element, but not marked nil var text = child.data; if (isc.Browser.isMoz && text.length > 4000) return element.textContent; return text;},// whether an element is a text nodeisTextNode : function (element) { if (element == null) return false; var nodeType = element.nodeType; // 3:text, 4:cdata, 8:comment return (nodeType == 3 || nodeType == 4 || nodeType == 8);},// whether an element has only a single child, of type text or CDatahasElementChildren : function (element) { if (element == null || (element.hasChildNodes != null && element.hasChildNodes() == false)) return false; var childNodes = element.childNodes; if (!childNodes) return false; var length = childNodes.length; for (var i = 0; i < length; i++) { var child = childNodes[i]; if (!this.isTextNode(child)) return true; } return false;},// JS -> XML// ---------------------------------------------------------------------------------------setAttributes : function (element, values) { var undef; for (var propName in values) { var value = values[propName]; if (value == null) { element.removeAttribute(propName); continue; } // setAttribute("attr", true) in IE stores "-1" (yes, seriously) if (isc.Browser.isIE && (value === true || value === false)) { value = isc.emptyString + value; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -