摘 要: 基于XQuery查詢語言的XBRL查詢引擎首先借助JavaCC工具處理輸入的XQuery語句形成抽象語法樹,而后根據XQuery查詢特點編寫程序遍歷此語法樹來簡化查詢語言的處理流程,降低查詢匹配的復雜度,提高查詢效率,利用“SAX+ DOM”方式解析XBRL文件并提取XQuery語句所查詢的數據信息。SAX方法可以提高查詢效率并節省內存消耗,DOM方法可以支持對XBRL文件的上下文相關查詢及頻繁查詢。實驗證明,將二者結合起來應用滿足高查詢效率和低內存消耗雙重需求。
關鍵詞: XBRL; XQuery; 解析器
XBRL[1](可擴展商業報告語言)是XML語言的擴展應用,主要面向金融財政領域,對其進行數據挖掘和分析具有重大意義,在實際項目中如何方便高效率地對其進行數據提取并降低內存消耗是需要解決的問題。
W3C制定的XQuery語言中的FLOWR[2]可以高效率地對XBRL進行查詢處理,目前國內外有很多支持XQuery查詢語言的查詢引擎,如國外開源的XQEngine是一個基于JavaBean的用來查詢本地XML文檔的XQuery查詢引擎,該引擎使用SAX[3]解析方式來解析并提取XML中的所需信息,節省了內存也保證了查詢速度。但是由于XBRL中的實例文件是承載財政數據的文件,其節點間存在密切的數據關聯關系,用戶多使用頻繁查詢及復合查詢等查詢實例文件進行數據分析,“邊讀邊扔數據”的SAX方式無法滿足這一需求。本文提出的SAX+DOM方式可以解決這一問題,同時在一定程度上比純DOM[4]讀取方式節省了大量內存。
圖1給出了基于XQuery的商業報告查詢引擎的整體框架,主要分為XQuery預處理模塊、查詢優化器和查詢執行器3個模塊。傳統的查詢優化包括Schema模式優化[5]、 XQuery語句查詢重寫、XML文檔索引技術、XQuery語句規范化等[6],而本文涉及的解析方式創新及抽象樹的遍歷簡化則是從查詢引擎內部實現角度對XQuery查詢進行了優化,下面著重對查詢引擎內部優化中的XQuery預處理模塊及查詢執行器進行具體闡述。
1 遍歷Javacc生成的抽象語法樹
XQuery查詢語言被設計用來查詢XML(XBRL本質上也為XML)文件,其語法中的FLWOR表達式是最重要的,它代表 For-Let-Where-Order by-Return。For子句通過將節點綁定到變量,以便繼續循環遍歷序列中的每一個節點;let子句為一個變量賦一個值或一個序列;return 子句定義每個元組要返回的內容;對于where子句,如果其有效布爾值為真,那么該元組就被保留,并且它的變量綁定用在return子句中,反之該元組就被廢棄[7]。
在查詢預處理模塊,通過JavaCC[8]工具和W3C已定義的XQuery語法規則來進行詞法分析,將輸入的XQuery語句查詢語句中的每個成分都變成帶有特定屬性的節點并生成與之相對應的類(例如顯示的是MainModule等,則語法解析時JavaCC中的JJtree以這些類為節點在內存中生成樹形結構),然后編寫程序遍歷抽象語法樹。下面的算法流程為遍歷FLOWR表達式中For語句對應的抽象語法樹分支的流程,其中MainModule等均為使用JavaCC工具并根據W3C XQuery規范中XQuery BNF定義生成的語法樹中的抽象樹節點名字。XQuery語句解析算法的流程圖如圖2所示,首先取得根節點XQuery開始處理語法樹的內容,循環三次依次得到QueryList、Module和MainModule節點。
判斷節點MainModule是否為null,如為null,則報錯;如果不為null,取出第一個節點prolog和第二個節點QueryBody,分別對這兩個節點進行分析處理。
對prolog節點進行處理,左節點prefix和右節點url為命名空間的格式,保存為名值對。在實際項目操作中,QueryBody環節只會出現一個FLOWR語句,很少會有嵌套語句,本文只給出FLOWR的子節點為ForClause的情況,其他子節點暫不考慮。
判斷ForClause子節點類型,若為用來表示變量所對應的Xpath值PathExpr節點,則取出PathExpr節點的子節點判斷其類型。節點為函數的情況下則調用預定義函數,根據字段名稱在節點樹中定位并保存其內容;如節點類型為分隔符,則表示任意節點都可以作為下一個節點字段的起始狀態。最后將PathExpr節點的處理結果ResultList與Varname變量節點對應并保存。
2 結合SAX和DOM解析XBRL文件
對于XBRL文件來說,存在DOM和SAX兩種基本的解析手段。如果進行一次性查詢或非頻繁性查詢,建議采用內存消耗小的基于事件驅動模型的SAX解析方式,無需像DOM解析方式中為所有節點創建對象。但當需要大量上下文相關查詢及頻繁查詢時,尤其在查詢后經修改合并而得到的結果集上進行復查詢,則采用DOM方式為好。
XBRL文件解析分為兩種情況: (1)分類標準比較穩定,對其進行首次框架解析后將在數據庫中將其保存,可以采取單獨的SAX解析方式簡單地進行逐條解析;(2)實例文件承載大量重要數據,用戶多使用頻繁查詢及復合查詢等查詢實例文件來進行數據分析,在這種情況下DOM解析方式是最好的選擇。但是實例文件數量較多時,為XBRL實例文件中所有節點創建對象會大大增加內存需求。這時需要考慮將這兩種方式結合起來使用。在讀取實例文件數據時,利用SAX只讀取用戶所需要的若干小數據文件,并為小數據文件在內存中建立DOM對象,每次讀取新的數據片段,則在已存在的DOM對象上進行添加或者修改等操作。這樣做既有效地節省了大量資源,也充分利用了DOM對象的易操作性。
圖3為兩種解析方式結合的工作原理,其處理過程為:首先SAX對象objSAX的parse方法被調用來解析XBRL實例文件,在startElement事件中進行元素篩選,如為所需元素,則保存該元素及其子節點元素,在endElement事件中調用DOM對象的loadXML()方法將數據轉化為DOM樹,從而可以方便下一步的數據處理(如頻繁查詢、信息更新等)。這樣不僅保證了快速解析,也在更大程度上支持XQuery的上下文查詢及信息檢索。
3 系統實驗結果
實驗環境采用Inter Pentium Dual E2160 @1.80 GHz、1 GB 內存、Windows XP。
本文引擎解析文件時利用SAX+DOM方式,下面的實驗結果證明了使用這種方式的優勢,如圖4所示。使用SAX+DOM方式處理時,只需將所需內容裝入內存,故文檔處理的時間不會因為文檔的大小發生太大變化,事件均小于0.003 s。而采用DOM方法處理文檔,當文檔大小達到一定程度時,需要使用硬盤的虛擬內存,其處理時間也會急劇增大。
本文所提出的查詢引擎簡化了XQuery語句解析流程和復雜度,節點尋址路線相對于開源軟件XQEngine變得簡單。本實驗利用上述兩種引擎對中國Taxonomy的cas_core_2010-09-30.xsd文件進行查詢,查詢語句如圖5所示,兩個解析器都正確地返回結果2 847個節點。本文提出的查詢引擎用時1.25 s,XQEngine因其復雜的XQuery解析算法使得用時稍長,為3.7 s。
本文在深入剖析XQuery查詢語法特點后,結合“SAX+自定義DOM”文件解析方式完成對FLWOR抽象語法樹的遍歷及查詢信息讀取,來簡化XQuery語句的查詢處理流程并降低查詢匹配的復雜度,設計并實現了XBR查詢引擎,提高了查詢效率,降低了內存消耗。該引擎在項目中的數據信息查詢模塊起著重要作用。
參考文獻
[1] 呂科,劉曉峰.XBRL技術原理與應用[M].北京:電子工業出版社,2007.
[2] WALMSLEY P. XQuery權威指南[M].王銀輝,譯.北京:電子工業出版社, 2009.
[3] 馮進,丁博,史殿習,等.XML解析技術研究[J].計算機工程與科學,2009,31(2):120-124.
[4] 楊波.DOM解析器OnceDOMParser的設計與實現[D].北京:中國科學院研究生院(軟件研究所),2005.
[5] 孟曉峰,王宇,王小峰. XML查詢優化研究[J]. 軟件學報, 2006,17(10):2069-20.
[6] PAPARIZOS S, PATEL J M, JAGADISH H V. SIGOPT:Using schema to optimize XML query processing international[C]. Istanbul: International Conference on Data Engineering, 2007.
[7] 華珊珊,謝鉉洋.XML查詢語言XQuery的研究與實現[J].計算機技術與發展, 2009,19(4): 48-50.
[8] VISWANDAHA S, SANKAR S. Java Compiler Compiler(JavaCC)-The java papser generator[J].URL:https://javaCC.dev.java.net.2006.