我有一个像这样的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等。
从这个问题中,我收集了XmlDocument是否易于使用,那会很棒,更简单,越好,因为我对解析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"
?
我认为LINQ to 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();
为了更清楚地说明,我将尝试描述该查询的作用:
- 采用作为文档根元素后代的所有名为"类别"的元素
- 仅选择类别,该类别的"名称"属性具有值"Bebidas"
- 将该类别中的"食物"元素投影到一个集合中
- 选择属性值等于"si"的"食物"元素
- 将结果元素投影到格式为"名称 - 价格"的字符串中
LINQ to XML很好,但很快就会变得混乱。如果要使用 XML,则应知道如何使用 XPaths 来筛选所需的节点。
试试这个:
foreach (XmlNode node in doc.SelectNodes("//Food[@cocina = 'si']"))
{
Console.WriteLine(node.SelectSingleNode("Name").InnerText
+ " "
+ node.SelectSingleNode("Price").InnerText);
}
XPath 在任何地方都受支持;LINQ to XML 在 .NET 之外对你没有好处。
您应该使用 XPATH,而不是编写代码来检索这些节点。
您想要的 XPath 表达式是 "//Food[@cocina = 'si']"
IE使用doc.selectNodes(xpath)作为使用XPath的方式,好的浏览器使用doc.evaluate()。
看看这里: http://www.w3schools.com/xpath/xpath_examples.asp