問題是sitemapindex
元素定義了一個默認名稱空間。您需要在選擇節點時指定命名空間,否則將無法找到它們。例如:
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", "http://www.sitemaps.org/schemas/sitemap/0.9");
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
通常來說,使用XmlNameSpaceManager
時,你可以離開前綴爲空字符串指定您希望該命名空間是默認的命名空間。所以,你會覺得你可以做這樣的事情:
// WON'T WORK
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("", "http://www.sitemaps.org/schemas/sitemap/0.9"); //Empty prefix
XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap", manager); //No prefixes in XPath
但是,如果你嘗試的代碼,你會發現,它不會找到任何匹配的節點。原因是在XPath 1.0(這是XmlDocument實現的)中,當沒有提供名稱空間時,它始終使用空名稱空間,而不是默認名稱空間。因此,如果您在XmlNamespaceManager
中指定默認名稱空間,則無關緊要,XPath不會使用它。引述從Official XPath Specification有關段落:
的QName在節點測試擴展成使用 命名空間聲明從表達式上下文中的擴展名。這與 中的元素類型名稱完全相同 擴展方式除了不使用用xmlns聲明的默認名稱空間外:如果012xxQName沒有前綴,則名稱空間URI爲空 (這個 與擴展屬性名稱的方式相同)。如果 QName的前綴在 表達式上下文中沒有名稱空間聲明,則會出錯。
因此,當您正在閱讀的元素屬於某個命名空間時,無法避免將命名空間前綴放入XPath語句中。但是,如果您不想將名稱空間URI放入代碼中,則可以使用XmlDocument
對象返回根元素的URI,在這種情況下,它是您想要的。例如:
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", xml.DocumentElement.NamespaceURI); //Using xml's properties instead of hard-coded URI
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
它怎麼樣?它是否成功加載文件?如果找到兩個站點地圖元素?它是否讀取任何一個sitemap子元素?我假設這些破折號在元素標籤不在實際的xml文件中,對吧? – 2012-07-05 16:06:21
xnList沒有被填充。(對不起破折號 - 沒有破折號) – Andrew 2012-07-05 16:08:11