2013-07-25 13 views
-1
let $d := doc('foo.xml') 

return concat('let $d := 

', $d) 

回報的XQuery CONCAT預期的方式不輸出文檔的XML

let $d := 

bar 

我需要它返回:

let $d := 

<foo>bar</foo> 
+0

mblakele已經'警告'您足夠了解生成代碼的可能危險,您打算評估或執行沒有中間控制。我很好奇,但更大的圖片。我們可能會建議替代路線,這將防止使用有風險的方法.. – grtjn

+0

這是一個一次性代碼生成一些xquery來加載一些數據。然而,我對緩解XQuery注入感興趣。目前我正在使用封裝xquery的「查詢對象」,並對變量使用直接的字符串替換。有沒有更好的辦法? (我確定有 - 可能是一個庫來支持查詢中值的安全替換?) – Ben

+0

那麼,如果確保注入的值只代表字符串,並且不允許,則可以防止很多問題過早關閉這些字符串,通過轉義特殊字符,首先在XML中插入事物,或其他。有一些供應商特定的擴展可能也有幫助。大多數XQuery解析器(包含MarkLogic的解析器)允許使用eval類型的函數,這些函數通常也允許參數替換。除此之外,MarkLogic還支持xdmp:value,一個輕量級的eval以及xdmp:unpath,用於解析存放XPath路徑類表達式的變量。 – grtjn

回答

5

閱讀fn:concat函數簽名,沒有理由期望它輸出XML。從http://www.w3.org/TR/xpath-functions/#func-concat

fn:concat(
    $arg1 as xs:anyAtomicType?, 
    $arg2 as xs:anyAtomicType?, 
    ...) 
as xs:string 

也就是說,它需要可變數量的原子項並返回一個字符串。所以如果你把它傳遞給一個XML節點,它會嘗試將它原子化並返回一個字符串結果。如果您尚未進入霧化,請嘗試string(doc($uri))以查看會發生什麼。

忽略這一點,它看起來像你試圖建立一個使用字符串操作的XQuery表達式 - 可能用於xdmp:eval?這很好,但不要通過使用xdmp:quote來傳遞XML。爲了正確性,性能和安全性的原因,這項工作的正確工具是一個外部變量。

xdmp:eval(' 
    declare variable $INPUT external ; 
    let $d := $INPUT 
    return xdmp:describe($d)', 
    (xs:QName('INPUT'), $d)) 
更好

然而,寫入字符串部分作爲單獨的XQuery模塊和相同的外部變量參數xdmp:invoke它。

爲什麼這樣呢?正確性,效率和安全性。如果你養成了盲目評估琴絃的習慣,那麼你正在設法解決問題。傳遞節點引用比引用大型節點更有效。當您將XML引用爲字符串時,您最終可能會使用XQuery重要字符,例如{。然後你必須逃避它們(或切換到使用xdmp:unquote,但這使得它效率更低)。任何轉義都將容易出錯。在SQL中,處理這種情況的經典方法是使用綁定變量,而對於XQuery,它是一個外部變量。與SQL中的綁定變量一樣,外部變量處理轉義。這也使得注入攻擊變得更加困難。

-2
let $d := xdmp:quote(doc('foo.xml')) 

return concat('let $d := &#xD;&#xD;', $d) 
+1

似乎有點不公平回答你自己的問題:) –

+1

Upvoted讓我輕笑 – Ben

+1

http://stackoverflow.com/help/self-answer說「Stack Exchange一直明確地鼓勵用戶回答自己的問題。」雖然這可能不是最好的答案。 – mblakele

0

使用管道連接。 例如:$ a || $ b 如果您的變量屬於原子類型,那麼您可以使用字符串連接。 例如:,$ a || fn:string-join(($ b),「,」)