1

I have been struggling with the XMLReaderClass in c# for some time now and just can't seem to get the concept. Basically I want to loop through the XML File and if the category in the xml doc is the same as the category I have passed it in, I want to add its name to a List.

here is the 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>

and here is my code I have started to work on but didn't get very far :(

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
    This is a perfect task for LINQ. Are you intentionally trying not to use that? Commented Jan 23, 2012 at 17:37
  • 1
    Why do you want to use XmlReader instead of the more friendly XDocument or XmlDocument classes? Commented Jan 23, 2012 at 17:37
  • long story short, I have to use the XMLReader Commented Jan 23, 2012 at 17:47
  • What is the long story, are you stuck with .NET 2.0? You can use an XMLReader to load the data into an XDocument like @Jeff Mercado suggested Commented Jan 23, 2012 at 17:51

4 Answers 4

1

Using an XmlReader here will just be a pain to use. Use LINQ to XML here using that API instead, it will make your life easier.

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);
    }
}

If for whatever reason you still wish to use the XmlReader, you could read it like this:

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);
}
Sign up to request clarification or add additional context in comments.

2 Comments

long story short, I have to use the XMLReader
Fortunately, you can load the contents of the reader here as I have shown so it's not a problem. You just shouldn't be using the XmlReader yourself to process it, that's the painful part.
1

For extremely large XML files, using XmlReader to scan through the document can be more efficient than using XmlDocument or XDocument, which require that the entire file be loaded into memory. Access the XmlReader.LocalName property to determine the kind of element the reader is positioned on, and call the XmlReader.GetAttribute() method to get the value of an attribute.

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);
}

Comments

0

I would use LINQ to XMl (XDocument) instead of the old reader. This will get you started (assuming your xml is in a file in your c:\temp directory):

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

2 Comments

long story short, I have to use the XMLReader
@shenn Bummer -- Michael Liu's implementation looks pretty good.
0

Check out Linq to XML, here is an example looking for a specific attribute

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

1 Comment

long story short, I have to use the XMLReader

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.