2012-03-06 111 views
2

令我驚訝的是,我正在與一個非常基本的XQuery問題搏鬥,即在主XQuery模塊和導入的庫模塊之間共享全局變量的正確方法是什麼。簡而言之,我想定義一個可以在任何地方重用的全局變量(即在所有(導入的)XQuery模塊中),並且正在努力尋找宣佈這樣一個變量的最佳位置。XQuery:跨(導入)模塊共享全局變量

假設我有以下幾個主要的XQuery(test.xq):

import module namespace global="global" at "global.xq"; 
import module namespace test2="test2" at "test2.xq"; 

declare variable $test := 'test!'; 

test2:echo() 

該模塊導入以下庫模塊:

  • global.xq:

    module namespace global="global"; 
    
    declare variable $global:test := 'global!'; 
    
  • TEST2 .x: module namespace test2 =「test2」;

    import module namespace global="global" at "global.xq"; 
    
    declare function test2:echo() { 
        $global:test 
    }; 
    

這工作,但給我留下了一些問題:

  • 這是做到這一點的方式:

    • 定義全局變量(如$全球:測試)在一個單獨的庫模塊中(例如global.xq)
    • 將模塊導入需要提供的任何模塊訪問其變量

  • 有沒有辦法訪問導入的庫模塊(例如test2.xq)中的主XQuery模塊(例如$ test)中聲明的變量?

任何人都可以闡明這一點嗎?我想我發現自己在這個概念上掙扎的主要原因是因爲我習慣於eXist的行爲,這可能比它應該放鬆。在存在,test2.xq模塊可以直接參考$全局:測試變量,而不用導入global.xq模塊:

module namespace test2="test2"; 
declare namespace global="global"; 

declare function test2:echo() { 
    $global:test 
}; 

由於這部作品中不存在,但不是在撒克遜人,我就開始琢磨什麼在(導入的)XQuery模塊中定義和使用全局變量的正確方法。

親切的問候,

羅恩

回答

3

顯然存在需要,可能是你熟悉的,從XSLT.In那裏,你也可以指通過進口/包括宣佈當前模塊外部變量和參數的方法'祖先'模塊(在包含/進口鏈中較高)。

據我所知,不符合XQuery標準!

能夠使用它顯然是非常實用的,但爲什麼不這樣做有幾個很好的理由。理想情況下,模塊是自包含的,可重用的組件,而當它們依賴於這種外部參數/變量時不再是這種情況。將上下文信息作爲參數傳遞給這些函數會更好。不總是看起來優雅,但最終是更好的設計。

一些實現提供了使用重定義變量值的備選選項。 MarkLogic有xdmp:set命令,我相信saxon也有變量賦值(或者是在XSLT中?)。你可以用它來'初始化'模塊。儘管這些模塊不是對象,所以儘量避免使用這種方法來保存有狀態的信息。這也意味着你會依賴實現特定的功能。除非你能夠使用更新工具。不知道這是打算這樣的方式,雖然..

+0

謝謝你的想法。我非常清楚,我可能會遇到基於非標準行爲的假設。然而,我在網上找不到關於這種設計模式的許多有用提示。我不喜歡針對這種基本需求的特定於供應商的擴展。你會推薦我的原始問題中的工作方法(即在專用庫模塊中定義全局變量並根據需要導入)作爲使所有(導入)XQuery模塊都可訪問全局變量的標準方法嗎?或者你看到其他(符合)的可能性? – rvdb 2012-03-06 15:01:07

+1

@rvdb我建議通過參數傳遞這樣的值給每個調用。將大量的上下文信息收集到一個小的XML片段中非常容易,並且可以通過它。它是迄今爲止最可擴展和最乾淨的。 像你這樣導入一個共享的全局模塊是最明智的選擇,除非你有足夠的理由想要初始化我描述的行爲。 HTH! – grtjn 2012-03-06 16:21:50

1

什麼這些「變量」在您的實際使用情況?顧名思義,他們是否需要能夠改變? (如果是這樣,將它們放在文檔中可能是正確的事情)。如果它們只是常量,那麼你給的方法 - 將它們放入單個模塊/名稱空間並根據需要導入 - 可能是正確的。坦白地說,編寫你的模塊來假設其他地方定義的東西,但沒有定義其他地方應該在哪裏,這使我容易冒險 - 如果沒有其他原因,通過讓讀者更難以遵循控制流程。因此,我有點不清楚爲什麼這種行爲是可取的。

考慮將您的配置封裝在文檔中,並將該文檔作爲參數傳遞給您的函數調用。

+0

不,他們是常數;我正在考慮更多的配置文件,其中包含可由泛型代碼使用的特定於應用程序的值。然後通用代碼可以用於不同的應用程序,每個應用程序都有自己的配置值。 我想你的第二個評論涉及我提到的eXist行爲?在這種情況下,我確實同意:我寧願採取符合規格的路線。 – rvdb 2012-03-06 16:41:39

+0

@rvdb - 啊,gotcha。我個人提供配置值的方法是通過配置文件注入配置文件,並將其作爲參數傳遞給需要此類值的任何調用。現在,我將這個文檔作爲上下文參數傳遞給實際的調用,而不是將其存儲在數據庫中,儘管這種特定的方法是我不確定我是長期銷售的......但是方式,明確比隱含更好。 – 2012-03-06 17:45:36

+0

@rvdb ...實際上,它看起來像grtjn獨立地提出了相同的方法;我正在閱讀,作爲我自己使用的維護/驗證水平。 :) – 2012-03-06 17:47:41