问题
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);
}
回答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);
}
回答2:
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);
}
回答3:
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"));
}
回答4:
Check out Linq to XML, here is an example looking for a specific attribute
http://msdn.microsoft.com/en-us/library/bb387041.aspx
来源:https://stackoverflow.com/questions/8975961/parsing-xml-data-using-c-sharp