前一篇文章SAP UI5 应用的 OData 元数据请求响应的解析原理分析我们介绍了 SAP UI5 OData 元数据解析的入口。本文继续介绍基于 DOMParser 的 XML 数据解析原理。
入口如下:
var xmlParse = function (text) { /// <summary>Returns an XML DOM document from the specified text.</summary> /// <param name="text" type="String">Document text.</param> /// <returns>XML DOM document.</returns> /// <remarks>This function will throw an exception in case of a parse error.</remarks> var domParser = window.DOMParser && new window.DOMParser(); var dom; if (!domParser) { dom = msXmlParse(text); if (!dom) { xmlThrowParserError("XML DOM parser not supported"); } return dom; }
dom = domParser.parseFromString(text, “text/xml”); 这是一个原生方法调用。
成功解析出的 dom 元素对象:
下面开始遍历这个 dom 对象:
拿到第一个元素:
递归操作:
解析成功的 metadata:
解析出的 entityType:
解析成功的元数据,存储在 response.data 里:
触发 metadata 加载成功的 callback:
ODataMetadata.prototype._handleLoaded = function(oMetadata, mParams, bSuppressEvents) { var aEntitySets = []; this.oMetadata = this.oMetadata ? this.merge(this.oMetadata, oMetadata, aEntitySets) : oMetadata; this.oRequestHandle = null; mParams.entitySets = aEntitySets; // resolve global promises this.fnResolve(mParams); if (this.bAsync && !bSuppressEvents) { this.fireLoaded(this);
抛出 loaded 事件:
该事件的参数为 metadata 的 json 对象格式和 xml 文本:
OData 元数据就绪后,执行初始化操作:
ODataModel.prototype.initialize = function() { // Call initialize on all bindings in case metadata was not available when they were created var aBindings = this.getBindings(); aBindings.forEach(function(oBinding) { oBinding.initialize(); }); };
遍历所有的 binding 数据源。
SAP UI5 使用的 datajs.js, 是一种开源的跨浏览器 JavaScript 程序库,可以让开发人员在浏览器环境里消费 OData 服务。
在 SAP UI5 库里位于路径 sap/ui/thirdparty 下面,SAP 对该文件也做了一些自己的修改,通过注释 BEGIN: MODIFIED BY SAP 和 END: MODIFIED BY SAP 来标识。
一个例子如下:
odata.defaultHandler = { read: function (response, context) { /// <summary>Reads the body of the specified response by delegating to JSON and ATOM handlers.</summary> /// <param name="response">Response object.</param> /// <param name="context">Operation context.</param> // ##### BEGIN: MODIFIED BY SAP // added response.body check and removed assigned(response.body) call...for the case that if body is empty string...don't process any response body data if (response && response.body && response.headers["Content-Type"]) { // ##### END: MODIFIED BY SAP dispatchHandler("read", response, context); } },