下面是我正在處理的問題的簡化版本:我有一堆xml數據,用於編碼有關人員的信息。每個人都有唯一的'id'屬性,但他們可能會有很多名字。例如,在一個文檔中,我可能會發現編寫更高效的xquery代碼(避免冗餘迭代)
而在另一個我可能會發現:
<person id=1>Sir Paul McCartney</person>
<person id=2>Richard Starkey</person>
我想使用XQuery產生一個新文檔,列出與給定ID相關聯的每一個名字。即:
<person id=1>
<name>Paul McCartney</name>
<name>Sir Paul McCartney</name>
<name>James Paul McCartney</name>
</person>
<person id=2>
...
</person>
我在XQuery目前這樣做的方式是這樣的(僞代碼式的):
let $ids := distinct-terms([all the id attributes on people])
for $id in $ids
return <person id={$id}>
{
for $unique-name in distinct-values
(
for $name in ([all names])
where $name/@id=$id
return $name
)
return <name>{$unique-name}</name>
}
</person>
的問題是,這實在是太慢了。我想象的瓶頸是最內層的循環,每個id(其中大約有1200個)會執行一次。我正在處理一些公平的數據(300 MB,分佈在大約800個xml文件中),因此即使在內部循環中執行一次查詢也需要大約12秒,這意味着重複1200次需要大約4次小時(這可能是樂觀的 - 該過程至今已經運行了3個小時)。它不僅速度慢,而且使用了大量的虛擬內存。我使用的是Saxon,爲了避免出現內存錯誤,我必須將java的最大堆大小設置爲10 GB(!),並且它目前使用6 GB的物理內存。
因此,這裏就是我真的很想這樣做(在Python化僞代碼):
persons = {}
for id in ids:
person[id] = set()
for person in all_the_people_in_my_xml_document:
persons[person.id].add(person.name)
在那裏,我只是做了它的線性時間,只有一次掃描的XML文檔。現在,有沒有辦法在xquery中做類似的事情?當然,如果我能想象得到它,一種合理的編程語言應該能夠做到這一點(他說,混沌地說)。我想這個問題是,與Python不同,xquery沒有(據我所知)具有像關聯數組一樣的東西。
有沒有一些聰明的方法呢?如果不這樣做,是否有什麼比我用來實現目標的xquery更好?因爲真的,我投擲在這個相對簡單的問題上的計算資源有點荒謬。
我覺得同樣的事情使用VTD-XML和XPath可以更快地完成,這是否會成爲您考慮的選項? – 2010-05-13 02:40:03
好問題(+1)。查看我的答案以獲得簡單高效的XSLT 2.0解決方案。 – 2010-09-04 17:11:16