Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中读取xml文件?_C#_Xml - Fatal编程技术网

如何在C#中读取xml文件?

如何在C#中读取xml文件?,c#,xml,C#,Xml,我有一个读取xml文件的代码。有些部分我不明白。 据我所知,代码将创建一个包含2个元素的xml文件, “产品”和“其他详细信息”。为什么我们只需要使用writer.WriteEndElement(); 一次当我们两次使用writer.writeStarteElement时,我们不是应该互相关上吗 writer.writeStarteElement语句与writer.WriteEndElement()语句 using System.Xml; public class Program {

我有一个读取xml文件的代码。有些部分我不明白。 据我所知,代码将创建一个包含2个元素的xml文件, “产品”和“其他详细信息”。为什么我们只需要使用writer.WriteEndElement(); 一次当我们两次使用writer.writeStarteElement时,我们不是应该互相关上吗 writer.writeStarteElement语句与writer.WriteEndElement()语句

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();
    }
}
我不明白这部分:

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);
                }
            }
注意while(reader.NodeType!=XmlNodeType.EndElement)条件是如何被使用两次的

为什么我们不需要具体说明

if(reader.NodeType==XmlNodeType.Element了解其他详细信息)
就像我们对产品所做的那样

像这样

if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "OtherDetails")
{} 

要回答您的第一个问题:

正如政府所说:

关闭所有打开的元素或属性,并将写入程序恢复到开始状态

因此,它将自动为您关闭任何打开的元素。事实上,您可以完全删除对
WriteEndElement()
的调用,它仍然可以正常工作

正如人们在上面的评论中所说的,你也许应该考虑使用LINQ to XML.< 它可以使事情变得容易得多。例如,要使用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());
如果从XML中读取数据,可以使用从文件中加载XML,然后将数据取出,操作非常简单:

double price     = double.Parse(doc.Descendants("Price").Single().Value);
string brandName = doc.Descendants("BrandName").Single().Value;
或者(铸造):


(如果你想知道我们到底怎样才能像那样投射出一个XElement类型的物体:那是因为。)

如果你需要向前看(没有阅读或研究),下面是我所做的:

我最近为我的MenuStrip for WinForms编写了一个自定义XML解析方法(它有数百项,XML是我最好的选择)

//加载文档
//我从名为TempResources的C#资源文件中加载了我的
XDocument doc=XDocument.Load(newmemoryStream(Encoding.UTF8.GetBytes(TempResources.Menu));
//获取根元素
//(var是一个自动令牌,它将成为您分配给它的内容)
var elements=doc.Root.elements();
//遍历子元素
foreach(元素中的XElement节点)
{
//如果知道属性的名称,可以调用它
//我的名字是“名字”
//(如果您不知道,可以调用node.Attributes()-这有名称和值)
WriteLine(“加载列表:{0}”,node.Attribute(“name”).Value);
//在我的例子中,每个孩子都有额外的孩子,他们都是一样的
//*.Cast()将为我提供可以使用的数据类型中的数组
//menu_recurse(…)只是我的一个复活助手方法
菜单递归(node.Elements().Cast().ToArray());
}

(我的答案也可以在这里找到:-虽然不幸的是它不是Linq)

假设如果您想读取xml文件,我们需要使用数据集,因为xml文件在内部使用数据集转换为数据表。使用以下代码行访问该文件并将数据集与xml数据绑定

    DataSet ds=new DataSet();
    ds.ReadXml(HttpContext.Current.Server.MapPath("~/Labels.xml");

数据集由许多数据表组成,这些数据表的数量取决于xml文件中父子标记的数量

您必须使用XmlWriter吗?如果您可以使用LINQtoXML,那么编写代码就会简单得多。我更喜欢使用XmlDocument来读取XML文件。您可以轻松地在每个节点和每个节点的子节点之间循环。@HH您尝试过Linq2Xml吗?您所说的一切都可以用它来完成。@I4V我没有尝试过Linq2Xml,但我对XmlDocument没有任何问题(尽管我听到了很多抱怨)。要回答您关于为什么这行代码被使用了两次的问题,是因为
reader.Read()
提高了读取器的内部索引,从而改变了它的值,因此,你需要重新评估读者所拥有的是否是你想要的。
double price     = (double) doc.Descendants("Price").Single();
string brandName = (string) doc.Descendants("BrandName").Single();
// 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()));
}
    DataSet ds=new DataSet();
    ds.ReadXml(HttpContext.Current.Server.MapPath("~/Labels.xml");