2011-10-21 174 views
5

使用MarkLogic,但這可能是一個通用的XQuery問題。如何獲得孩子元素,但沒有他們的孩子?

我:

<library> 
    <books> 
    <book title="whatever"> 
     <publisher>Random</publisher> 
     ....more children 
    </book> 
    <book title="another"> 
     <publisher>Simon</publisher> 
     ....more children 
    </book> 
    ... 
    </books> 
</library> 

我想與他們的title屬性返回所有[圖書]元素,但我不希望任何一本書,例如子女的[發佈]。我如何以正統和高性能的方式實現這一目標?

相關問題:有時我可能想要一些的孩子,但不是其他人,例如,獲取所有書籍元素和他們的出版商子元素,但沒有其他孩子。

謝謝。

回答

4

XQuery的(實際上是XPath,它是XQuery的一個子集)/library/books/book技術上你想要做什麼 - 它返回一組書的元素,而不是其他。一些API將返回對書籍元素的引用,並讓你決定你想要對它們做什麼,例如顯示它們的標題。但是,許多工具和API會將這些書籍元素與植根於本書的整個子樹一起復制,而對於數據庫而言,這通常是通過網絡從服務器傳輸到客戶端的結果。在這種情況下,您不想選擇現有的書籍元素,您想要構建包含書籍元素中信息子集的新文檔。要做到這一點,你可以使用XQuery元素構造:

for $b in /library/books/book 
return <book title="{$b/@title}"/> 
+0

謝謝Michael!在我看來,這看起來似乎是最優雅的方法。 – bethesdaboys

1

可能有更簡單的方法...但我認爲這樣的事情會複製屬性瓦特/其他的孩子。警告:未測試的代碼

for $i in doc()//book 
return <book>{ 
    for $a in $i/@* 
    return $a 
}</book> 
+0

謝謝,這是有益的,因爲它提供了我一個意義更普遍的做法。 – bethesdaboys

0

我覺得一個稍微好一點的解決Michael Kay的將不枚舉各個所需的屬性,使其稍微一般。需要注意的是,/@返回一個屬性,而不僅僅是文本。

例如:

for $book in /library/books/book return <book>{$book/@*}</book> 

,甚至更普遍:

for $book in /library/books/book return element book {$book/@*} 
+2

你也不必使用。您可以使用如下的路徑表達式: /library/books/book/ {@ *}

+0

我喜歡這種方法的簡單性。然而,我的第一反應就是爲什麼你的x路徑中有元素? 我想我會採用這種方法。謝謝。 – Walt