парсинг данных XML с использованием c # - PullRequest
0 голосов
/ 23 января 2012

Я боролся с XMLReaderClass в c # уже некоторое время и просто не могу понять концепцию. По сути, я хочу пройтись по XML-файлу, и если категория в документе xml совпадает с категорией, в которой я его передал, я хочу добавить его имя в список.

вот XML

<?xml version="1.0" encoding="utf-8" ?>
<!-- Do not modify this xml file. -->
<Products>
    <product category="Food"  name="Baking potatoes" />
    <product category="Food" name="Chicken fillet" />
    <product category="Food" name="Chocolate gateau" />
    <product category="Food" name="Madras curry sauce" />
    <product category="Food" name="Organic carrots" />
    <product category="Food" name="Semi-skimmed milk" />
    <product category="Home" name="Washing powder" />
    <product category="Home" name="Rubber gloves" />
    <product category="Home" name="Spray wax" />
    <product category="Home" name="Dish soap" />
    <product category="Pet" name="Cat food" />
    <product category="Pet" name="Dog food" />
    <product category="Pet" name="Collar" />
    <product category="Pet" name="Leash" />
</Products>

и вот мой код, над которым я начал работать, но далеко не продвинулся: (

public ReadOnlyCollection<string> GetProductsByCategory(string category)
    {
        List<string> returnList = new List<string>();

        using (XmlReader productsReader = GetProductsReader())
        {


            productsReader.MoveToContent();
            while (productsReader.Read())

                if(productsReader.NodeType == XmlNodeType.Element)
            {
                if (productsReader)
                {
                    if productsReader
                }
            }

        }

        return new ReadOnlyCollection<string>(returnList);
    }

Ответы [ 4 ]

1 голос
/ 24 января 2012

Для очень больших файлов XML использование XmlReader для сканирования документа может быть более эффективным, чем использование XmlDocument или XDocument, которые требуют загрузки всего файла в память. Откройте свойство XmlReader.LocalName, чтобы определить тип элемента, на котором находится считыватель, и вызовите метод XmlReader.GetAttribute(), чтобы получить значение атрибута.

public ReadOnlyCollection<string> GetProductsByCategory(string category)
{
    List<string> products = new List<string>();

    using (XmlReader productsReader = GetProductsReader())
    {
        productsReader.MoveToContent();

        while (productsReader.Read())
        {
            if (productsReader.NodeType == XmlNodeType.Element &&
                productsReader.LocalName == "product" &&
                productsReader.GetAttribute("category") == category)
            {
                products.Add(productsReader.GetAttribute("name"));
            }
        }
    }

    return new ReadOnlyCollection<string>(products);
}
1 голос
/ 23 января 2012

Использование XmlReader здесь будет просто неудобно. Используйте здесь LINQ to XML с использованием этого API, это облегчит вашу жизнь.

public static ReadOnlyCollection<string> GetProductsByCategory(string category)
{
    using (var reader = GetProductsReader())
    {
        var doc = XDocument.Load(reader);
        var results = doc.Element("Products")
            .Elements("product")
            .Where(e => (string)e.Attribute("category") == category)
            .Select(e => (string)e.Attribute("name"))
            .ToList();
        return new ReadOnlyCollection<string>(results);
    }
}

Если по какой-либо причине вы все еще хотите использовать XmlReader, вы можете прочитать его так:

public static ReadOnlyCollection<string> GetProductsByCategory(string category)
{
    var results = new List<string>();
    var settings = new XmlReaderSettings
    {
        IgnoreWhitespace = true,
        IgnoreComments = true,
    };
    using (var reader = XmlReader.Create(GetProductsReader(), settings))
    {
        reader.MoveToContent();
        reader.ReadStartElement("Products");
        do
        {
            if (reader.IsStartElement("product"))
            {
                if (reader.MoveToFirstAttribute())
                {
                    string currentCategory = null;
                    string currentName = null;
                    do
                    {
                        switch (reader.Name)
                        {
                        case "category":
                            currentCategory = reader.ReadContentAsString();
                            break;
                        case "name":
                            currentName = reader.ReadContentAsString();
                            break;
                        }
                    } while (reader.MoveToNextAttribute());
                    if (currentCategory == category && currentName != null)
                        results.Add(currentName);
                }
            }
        } while (reader.ReadToNextSibling("product"));
    }
    return new ReadOnlyCollection<string>(results);
}
0 голосов
/ 23 января 2012

Проверьте Linq to XML, вот пример поиска определенного атрибута

http://msdn.microsoft.com/en-us/library/bb387041.aspx

0 голосов
/ 23 января 2012

Я бы использовал LINQ to XMl (XDocument) вместо старого ридера. Это поможет вам начать работу (при условии, что ваш xml находится в файле в вашем каталоге c: \ temp):

  var doc = XDocument.Load(@"c:\temp\testxml.xml");
  foreach(var element in doc.Elements("Products").Elements())
  {
    Console.WriteLine(element.Attribute("category"));
  }
...