前一篇文章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);
}
},
更多Jerry的原創文章,盡在:"汪子熙":