2010-04-07 490 views
6

我想使用XPath來選擇具有Location值的方面的項目,但是當前我甚至嘗試僅選擇所有項目失敗:系統愉快地報告它找到了0項,然後返回(而不是節點應該由foreach循環處理)。我會很感激幫助,無論是進行原始查詢還是隻讓XPath工作。C#XPath沒有找到任何東西

XML

<?xml version="1.0" encoding="UTF-8" ?> 
<Collection Name="My Collection" SchemaVersion="1.0" xmlns="http://schemas.microsoft.com/collection/metadata/2009" xmlns:p="http://schemas.microsoft.com/livelabs/pivot/collection/2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<FacetCategories> 
    <FacetCategory Name="Current Address" Type="Location"/> 
    <FacetCategory Name="Previous Addresses" Type="Location" /> 
</FacetCategories> 
    <Items> 
     <Item Id="1" Name="John Doe"> 
      <Facets> 
       <Facet Name="Current Address"> 
        <Location Value="101 America Rd, A Dorm Rm 000, Chapel Hill, NC 27514" /> 
       </Facet> 
       <Facet Name="Previous Addresses"> 
        <Location Value="123 Anywhere Ln, Darien, CT 06820" /> 
        <Location Value="000 Foobar Rd, Cary, NC 27519" /> 
       </Facet> 
      </Facets> 
     </Item> 
    </Items> 
</Collection> 

C#

public void countItems(string fileName) 
{ 
    XmlDocument document = new XmlDocument(); 
    document.Load(fileName); 
    XmlNode root = document.DocumentElement; 
    XmlNodeList xnl = root.SelectNodes("//Item"); 
    Console.WriteLine(String.Format("Found {0} items" , xnl.Count)); 
} 

還有更多比這個方法,但因爲這是獲取運行我假設所有的問題就出在這裏。致電root.ChildNodes準確地返回FacetCategoriesItems,所以我完全無所適從。

感謝您的幫助!

回答

17

您的根元素有一個名稱空間。您需要添加一個名稱空間解析器並在查詢中爲元素添加前綴。

This article解釋瞭解決方案。我修改了你的代碼,以便得到1結果。

public void countItems(string fileName) 
{ 
    XmlDocument document = new XmlDocument(); 
    document.Load(fileName); 
    XmlNode root = document.DocumentElement; 

    // create ns manager 
    XmlNamespaceManager xmlnsManager = new XmlNamespaceManager(document.NameTable); 
    xmlnsManager.AddNamespace("def", "http://schemas.microsoft.com/collection/metadata/2009"); 

    // use ns manager 
    XmlNodeList xnl = root.SelectNodes("//def:Item", xmlnsManager); 
    Response.Write(String.Format("Found {0} items" , xnl.Count)); 
} 
6

因爲你有你的根節點上的XML命名空間,也爲你的XML文檔中的「項目」沒有這樣的事,只有「[命名空間]:項目」,因此對於使用XPath的節點搜索時,你需要指定命名空間。

如果您不喜歡那樣,您可以使用local-name()函數來匹配所有其本地名稱(除前綴之外的名稱部分)是您正在查找的值的元素。這是一個有點醜陋的語法,但它的工作原理。

XmlNodeList xnl = root.SelectNodes("//*[local-name()='Item']");