2009-02-23 3 views
11

Я следующий файл:XMLNode запрос с использованием LINQ

<root> 
    <Product desc="Household"> 
    <Product1 desc="Cheap"> 
     <Producta desc="Cheap Item 1" category="Cooking" /> 
     <Productb desc="Cheap Item 2" category="Gardening" /> 
    </Product1> 
    <Product2 desc="Costly"> 
     <Producta desc="Costly Item 1" category="Decoration"/> 
     <Productb desc="Costly Item 2" category="Furnishing" /> 
     <Productc desc="Costly Item 3" category="Pool" /> 
    </Product2> 
    </Product> 
</root> 

Я хочу, чтобы узнать информацию, как: Всего позиций в дешевом и Дорогостоящие, список всех категории (например, приготовление пищи, Садоводство, украшении ...) , список отсортированной категории и выберите только Продукт, который является «Дорогостоящим»

Как я могу использовать LINQ. Я сделал это до сих пор:

XElement xe = XElement.Load(Server.MapPath("~/product.xml")); 
???? 

ответ

9

Ваша структура XML К сожалению, как он использует элемент продукта для трех уровней иерархии. У вас есть другие элементы, похожие на «домашние»?

Предположим, что мы хотим только бытовые из них, вы можете использовать:

Count элементов в каждой из дешевой/дорогостоящей

xe.Element("Product") // Select the Product desc="household" element 
    .Elements() // Select the elements below it 
    .Select(element => new { Name=(string) element.Attribute("desc"), 
          Count=element.Elements().Count() }); 

Список всех категорий

xe.Descendants() // Select all descendant elements 
    .Attributes() // All attributes from all elements 
    // Limit it to "category" elements 
    .Where(attr => attr.Name == "category") 
    // Select the value 
    .Select(attr => attr.Value) 
    // Remove duplicates 
    .Distinct(); 

К сортируйте это, просто используйте .OrderBy(x => x) в конце.

Выбрать '' дорогостоящие продукты

xe.Descendants() // Select all elements 
    // Only consider those with a "Costly" description 
    .Where(element => (string) element.Attribute("desc") == "Costly") 
    // Select the subelements of that element, and flatten the result 
    .SelectMany(element => element.Elements()); 
+1

мне действительно нужно научить себя LINQ ... звучит тааак легко так:) – balexandre

+0

Я изменил xml и он работает. Спасибо за ответ – 2009-02-23 08:46:05

+1

Я сомневаюсь, что Джон намеревался переименовать отдельные элементы * в * данные; вместо того, чтобы иметь разные имена на каждом уровне * ... –

9

Ну, лично я считаю, что проще с XmlDocument:

XmlDocument root = new XmlDocument(); 
    root.LoadXml(xml); // or .Load(path); 

    var categories = root.SelectNodes(
     "/root/Product/Product/Product/@category") 
     .Cast<XmlNode>().Select(cat => cat.InnerText).Distinct(); 
    var sortedCategories = categories.OrderBy(cat => cat); 
    foreach (var category in sortedCategories) 
    { 
     Console.WriteLine(category); 
    } 

    var totalItems = root.SelectNodes(
     "/root/Products/Product/Product").Count; 
    Console.WriteLine(totalItems); 

    foreach (XmlElement prod in root.SelectNodes(
     "/root/Product/Product[@desc='Costly']/Product")) 
    { 
     Console.WriteLine(prod.GetAttribute("desc")); 
    } 
Смежные вопросы