2012-05-30 179 views
0

我有一個是這樣的一個XML文檔:如何獲取具有某個屬性的節點的所有子節點?

<Menu> 
    <Category name="Comida Rapida"> 
     <Food cocina="si"> 
      <Name>Haburguesa</Name> 
      <Price>10</Price> 
     </Food> 
     <Food> 
      <Name>Papas Fritas</Name> 
      <Price>20</Price> 
     </Food> 
    </Category> 
    <Category name="Bebidas"> 
     <Food> 
      <Name>Pepsi</Name> 
      <Price>30</Price> 
     </Food> 
     <Food cocina="si"> 
      <Name>Coca Cola</Name> 
      <Price>40</Price> 
     </Food> 
    </Category> 
</Menu> 

我想要做的就是通過每<Category>檢查,如果該屬性是我需要的,例如「BEBIDAS」,所以部分我感興趣的是:

<Food> 
    <Name>Pepsi</Name> 
    <Price>30</Price> 
</Food> 
<Food cocina="si"> 
    <Name>Coca Cola</Name> 
    <Price>40</Price> 
</Food> 

現在,我有這個,我想要做類似的東西我做了什麼已經:

首先我要打印出所有:

Pepsi 30 
Coca Cola 40 

而且我想打印出來只有那些食物有屬性cocina="si",所以:

Coca Cola 40 

所以我有各種各樣的問題:

首先要使用的方法,我被大量的可能的方法和實現困惑:XmlDocument,XmlReader,XmlTextReader等

this question我收集XmlDocument更容易使用,這將是偉大的,更簡單的,th更好的是,因爲我可以欣賞到,因此對於解析Xml文件來說,這是相當新的。

我們在實際執行中,我已經嘗試了所有種類的東西沒有太大的更迭,我似乎能夠做一些部分而不是全部一起。

XmlNodeList elemList = doc.GetElementsByTagName("Category"); 
for (int i = 0; i < elemList.Count; i++) 
{ 
    Console.WriteLine(elemList[i].InnerXml); 
} 

這將輸出:

<Food><Name>Haburguesa</Name><Price>10</Price></Food><Food><Name>Papas Fritas</Name><Price>20</Price></Food> 
<Food><Name>Pepsi</Name><Price>30</Price></Food><Food><Name>Coca Cola</Name><Price>40</Price></Food> 

這是合理的,但現在,我該如何檢查,如果類具有屬性name="cocina"

我猜是這樣可以幫助:

for (int j = 0; j < elemList[i].Attributes.Count; j++) 
{ 
    //??     
} 

但我無法找到像XmlTextReader的MoveToAttribute()

再然後,我該如何檢查是否具有屬性cocina="si"

回答

2

我認爲LINQ到XML是這裏最簡單的方法:

你必須在這裏使用XDocument類。從字符串加載文件 - - 採用靜態方法XDocument.Parse(DOCUMENT)創建文檔對象或XDocument.Load(PATH) - 從給定路徑文件加載文檔。

之後,你可以很容易地找到你是一個這樣的查詢找什麼:

var doc = XDocument.Parse("<Menu> ... </Menu>"); 
var results = doc.Descendants("Category") 
       .Where(cat => (string)cat.Attribute("name") == "Bebidas") 
       .SelectMany(cat => cat.Elements("Food")) 
       .Where(food => (string)food.Attribute("cocina") == "si") 
       .Select(food => string.Format("{0} {1}", food.Element("Name"), food.Element("Price"))).ToList(); 

爲了更清楚我會盡力來形容該查詢並:

  1. 將名爲「Category」的所有元素作爲文檔根元素的後代
  2. 僅選擇該類別,其中「name」屬性的值爲「Bebidas」
  3. 項目該類別中的「食品」元素融入其中收集與「COCINA」屬性值等於「SI」
  4. 項目導致元素融入格式化字符串
  5. 選擇「食物」元素「的名字 - 價格」
+0

謝謝我正在嘗試它! – Trufa

+0

我冒昧並更改了Format的格式。 – Trufa

+0

我有一個問題,但我不知道如何使用'結果'。每個人都不應該做一個簡單的事情嗎另外,如果我正在閱讀文件,我應該使用XDocument.Load()對嗎? – Trufa

1

你應該使用XPATH,而不是編寫代碼來檢索這些節點。

要XPath表達式是 「//食品[@cocina = 'SI']」

IE使用doc.selectNodes(xpath的)作爲使用XPath的方式,良好的瀏覽器使用doc.evaluate() 。

到這裏看看:http://www.w3schools.com/xpath/xpath_examples.asp

+0

我來看看,謝謝。 – Trufa

2

LINQ to XML很好,但可能會變得很亂。如果你打算使用XML,你應該知道如何使用XPath來過濾你需要的節點。

試試這個:

foreach (XmlNode node in doc.SelectNodes("//Food[@cocina = 'si']")) 
{ 
    Console.WriteLine(node.SelectSingleNode("Name").InnerText 
     + " " 
     + node.SelectSingleNode("Price").InnerText); 
} 

的XPath到處都是支持的;在.NET之外,LINQ to XML對你來說並不好。

相關問題