2010-03-11 52 views
0

假設以下html(減去評論和「NBSP;」等是XQuery作爲是慣於處理)爲什麼這下面的代碼工作XQuery的本地名VS XPATH與HTML

for $first in fn:doc("file:///index.html")//element()[local-name() = "head"] 
    return <test>{ $first }</test> 

for $first in fn:doc("file:///index.html")//head 
return 
<test>{ $first }</test> 

不工作?

回答

3

因爲index.html是XHTML,而您要找的<head>位於XHTML名稱空間中。

第一個查詢忽略名稱空間,因爲您使用local-name()函數。

第二個查詢沒有,它明確要求在空名稱空間中的<head>

您需要

declare namespace x="http://www.w3.org/1999/xhtml" 

for $first in fn:doc("file:///index.html")/x:html/x:head 
return <test>{ $first }</test> 

注意,我避免使用//,因爲這經過了文檔的整個樹,即使在這種情況下<head>唯一可能的位置是事先知道的。明確地加快了XPath查詢的速度。

+0

謝謝!這就是我期望聽到的和絃......我只用//來減少xPath在測試 – jtzero 2010-03-11 16:18:11

+0

好的時候返回一個空序列()的機會。 ;-)我只是習慣於警告人們粗心使用'後代'軸。許多人沒有意識到後果就懶惰。 – Tomalak 2010-03-11 16:25:58

+0

我一直看到關於不使用'//'的建議,但事實並非總是如此。在.NET XPathNavigator中,每個節點都包含一個指向文檔中下一個具有相同名稱的節點的指針。查找第一個節點會掃描整個文檔,但在此之後導航很快。這意味着/ a/b/c/d可能比// d慢很多,因爲實現必須在途中找到a,b和c節點。我假定其他實現也具有相似的性能特徵 - 在數據庫中// d可能需要一次索引查找,但/ a/b/c/d需要4(和3個父子連接)。 – 2010-03-11 22:38:48