如何在 C# 中读取 xml 文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16489940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to read xml files in C# ?
提问by user2371290
I have a code which reads an xml file. There are some parts I dont understand. From my understanding , the code will create an xml file with 2 elements, "Product" and "OtherDetails" . How come we only have to use writer.WriteEndElement(); once when we used writer.WriteStartElement twice ? , shouldn't we close each writer.WriteStartElement statement with a writer.WriteEndElement() statement ?
我有一个读取 xml 文件的代码。有一些部分我不明白。根据我的理解,该代码将创建一个包含 2 个元素的 xml 文件,“Product”和“OtherDetails”。为什么我们只需要使用 writer.WriteEndElement(); 一次当我们使用 writer.WriteStartElement 两次时?,我们不应该用 writer.WriteEndElement() 语句关闭每个 writer.WriteStartElement 语句吗?
using System.Xml;
public class Program
{
public static void Main()
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create("Products.xml", settings);
writer.WriteStartDocument();
writer.WriteComment("This file is generated by the program.");
writer.WriteStartElement("Product"); // first s
writer.WriteAttributeString("ID", "001");
writer.WriteAttributeString("Name", "Soap");
writer.WriteElementString("Price", "10.00")
// Second Element
writer.WriteStartElement("OtherDetails");
writer.WriteElementString("BrandName", "X Soap");
writer.WriteElementString("Manufacturer", "X Company");
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
writer.Close();
}
}
using System;
using System.Xml;
public class Program
{
public static void Main()
{
XmlReader reader = XmlReader.Create("Products.xml");
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Product")
{
Console.WriteLine("ID = " + reader.GetAttribute(0));
Console.WriteLine("Name = " + reader.GetAttribute(1));
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.Read();
if (reader.Name == "Price")
{
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.Read();
if (reader.NodeType == XmlNodeType.Text)
{
Console.WriteLine("Price = {0:C}", Double.Parse(reader.Value));
}
}
reader.Read();
} //end if
if (reader.Name == "OtherDetails")
{
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.Read();
if (reader.Name == "BrandName")
{
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.Read();
if (reader.NodeType == XmlNodeType.Text)
{
Console.WriteLine("Brand Name = " + reader.Value);
}
}
reader.Read();
} //end if
if (reader.Name == "Manufacturer")
{
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.Read();
if (reader.NodeType == XmlNodeType.Text)
{
Console.WriteLine("Manufacturer = " + reader.Value);
}
}
} //end if
}
} //end if
} //end while
} //end if
} //end while
}
}
I don't get this part:
我不明白这部分:
if (reader.Name == "OtherDetails")
{
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.Read();
if (reader.Name == "BrandName")
{
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.Read();
if (reader.NodeType == XmlNodeType.Text)
{
Console.WriteLine("Brand Name = " + reader.Value);
}
}
notice how the condition while (reader.NodeType != XmlNodeType.EndElement)has been used twice ?
注意条件如何while (reader.NodeType != XmlNodeType.EndElement)被使用两次?
why is that we don't have to specify
为什么我们不必指定
if (reader.NodeType == XmlNodeType.Element for OtherDetails)as we did for Product,
if (reader.NodeType == XmlNodeType.Element for OtherDetails)正如我们对产品所做的那样,
like this
像这样
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "OtherDetails")
{}
回答by Matthew Watson
To answer your first question:
回答你的第一个问题:
As the MSDN documentation for XmlWriter.WriteEndDocument()says:
正如XmlWriter.WriteEndDocument()的MSDN 文档所说:
Closes any open elements or attributes and puts the writer back in the Start state.
关闭所有打开的元素或属性,并将编写器重新置于 Start 状态。
So it will automatically close any open elements for you. In fact, you can remove the call to WriteEndElement()altogether and it will still work ok.
所以它会自动为你关闭任何打开的元素。事实上,您可以WriteEndElement()完全删除对的调用,它仍然可以正常工作。
And as people are saying in the comments above, you should perhaps consider using Linq-to-XML.
正如人们在上面的评论中所说,您或许应该考虑使用 Linq-to-XML。
It can make things much easier. For example, to create the XML structure from your program using Linq-to-XML you can do this:
它可以让事情变得更容易。例如,要使用 Linq-to-XML 从您的程序创建 XML 结构,您可以执行以下操作:
var doc = new XDocument(
new XElement("Product",
new XAttribute("ID", "001"), new XAttribute("Name", "Soap"),
new XElement("Price", 10.01),
new XElement("OtherDetails",
new XElement("BrandName", "X Soap"),
new XElement("Manufacturer", "X Company"))));
File.WriteAllText("Products.xml", doc.ToString());
If you were reading data from the XML, you can use var doc = XDocument.Load("Filename.xml")to load the XML from a file, and then getting the data out is as simple as:
如果您正在从 XML 读取数据,您可以使用var doc = XDocument.Load("Filename.xml")从文件加载 XML,然后获取数据非常简单:
double price = double.Parse(doc.Descendants("Price").Single().Value);
string brandName = doc.Descendants("BrandName").Single().Value;
Or alternatively (casting):
或者(铸造):
double price = (double) doc.Descendants("Price").Single();
string brandName = (string) doc.Descendants("BrandName").Single();
(In case you're wondering how on earth we can cast an object of type XElement like that: It's because a load of explict conversion operators are defined for XElement.)
(如果您想知道我们究竟如何像这样转换XElement 类型的对象:这是因为为 XElement 定义了大量显式转换运算符。)
回答by TekuConcept
If you need anything strait forward (no reading or research), here is what I did:
如果你需要任何困难(没有阅读或研究),这就是我所做的:
I recently wrote a custom XML parsing method for my MenuStrip for WinForms (it had hundreds of items and XML was my best bet).
我最近为 WinForms 的 MenuStrip 编写了一个自定义 XML 解析方法(它有数百个项目,而 XML 是我最好的选择)。
// load the document
// I loaded mine from my C# resource file called TempResources
XDocument doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(TempResources.Menu)));
// get the root element
// (var is an auto token, it becomes what ever you assign it)
var elements = doc.Root.Elements();
// iterate through the child elements
foreach (XElement node in elements)
{
// if you know the name of the attribute, you can call it
// mine was 'name'
// (if you don't know, you can call node.Attributes() - this has the name and value)
Console.WriteLine("Loading list: {0}", node.Attribute("name").Value);
// in my case, every child had additional children, and them the same
// *.Cast<XElement>() would give me the array in a datatype I can work with
// menu_recurse(...) is just a resursive helper method of mine
menu_recurse(node.Elements().Cast<XElement>().ToArray()));
}
(My answer can also be found here: Reading an XML File With Linq- though it unfortunately is not Linq)
(我的答案也可以在这里找到:Reading an XML File With Linq- 尽管不幸的是它不是 Linq)
回答by Deepak Kothari
Suppose if you want to read an xml file we need to use a dataset,because xml file internally converts into datatables using a dataset.Use the following line of code to access the file and to bind the dataset with the xml data.
假设如果你想读取一个xml文件,我们需要使用一个数据集,因为xml文件在内部使用数据集转换成数据表。使用以下代码行访问文件并将数据集与xml数据绑定。
DataSet ds=new DataSet();
ds.ReadXml(HttpContext.Current.Server.MapPath("~/Labels.xml");
DataSet comprises of many datatables,count of those datatables depends on number of Parent Child Tags in an xml file
DataSet 由许多数据表组成,这些数据表的数量取决于 xml 文件中父子标签的数量

