C# 从XML加载和获取值

C# 从XML加载和获取值,c#,xml,C#,Xml,首先,我对C#不熟悉,但对其他编程有一些经验 语言。我现在遇到了一个我不知道如何解决的问题,所以到目前为止我还没有做任何事情,因为我真的不知道如何开始 我有一个XML文件,其中包含我希望匹配的数据,并将其子元素存储到变量中 例: 我想从xml中检索weeknumber值为“2”的week 并将所有子元素存储到应用程序中的单独变量中 int groupNumber=1 字符串开始时间=10:00 int startDay=8 字符串结束时间=12:00 int endDay=8 1. 10:

首先,我对C#不熟悉,但对其他编程有一些经验 语言。我现在遇到了一个我不知道如何解决的问题,所以到目前为止我还没有做任何事情,因为我真的不知道如何开始

我有一个XML文件,其中包含我希望匹配的数据,并将其子元素存储到变量中

例: 我想从xml中检索weeknumber值为“2”的week 并将所有子元素存储到应用程序中的单独变量中

  • int groupNumber=1
  • 字符串开始时间=10:00
  • int startDay=8
  • 字符串结束时间=12:00
  • int endDay=8

1.
10:00
8.
12:00
8.
1.
10:00
8.
12:00
8.
1.
10:00
8.
12:00
8.

自2007年以来,.Net Framework中就存在LINQ to XML API

c#


使用Xml序列化,然后解析结果

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication
{
    public class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        public static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(Root));
            Root root = (Root)serializer.Deserialize(reader);
        }
    }
    [XmlRoot("root")]
    public class Root
    {
        [XmlArray("weeks")]
        [XmlArrayItem("week")]
        public List<Week> week { get; set; }
    }
    public class Week
    {
        public int groupNumber { get; set; }

        private DateTime _starttime { get; set; }
        public string starttime 
        {
            get {return _starttime.ToString("HH:mm");}
            set { _starttime = DateTime.ParseExact(value, "HH:mm", System.Globalization.CultureInfo.InvariantCulture); } 
        }
        public int startday { get; set; }
        private DateTime _endtime { get; set; }
        public string endtime
        {
            get { return _endtime.ToString("HH:mm"); }
            set { _endtime = DateTime.ParseExact(value, "HH:mm", System.Globalization.CultureInfo.InvariantCulture); }
        }
        public int endday { get; set; }
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Serialization;
命名空间控制台应用程序
{
公共课程
{
常量字符串文件名=@“c:\temp\test.xml”;
公共静态void Main(字符串[]args)
{
XmlReader=XmlReader.Create(文件名);
XmlSerializer serializer=新的XmlSerializer(typeof(Root));
根根=(根)序列化程序。反序列化(读取器);
}
}
[XmlRoot(“根”)]
公共类根
{
[XmlArray(“周”)]
[XmlArrayItem(“周”)]
公共列表周{get;set;}
}
公共课周
{
public int groupNumber{get;set;}
私有日期时间_starttime{get;set;}
公共字符串起始时间
{
获取{return _starttime.ToString(“HH:mm”);}
set{u starttime=DateTime.ParseExact(值,“HH:mm”,System.Globalization.CultureInfo.InvariantCulture);}
}
公共int开始日期{get;set;}
私有日期时间_endtime{get;set;}
公共字符串结束时间
{
获取{return _endtime.ToString(“HH:mm”);}
set{u endtime=DateTime.ParseExact(值,“HH:mm”,System.Globalization.CultureInfo.InvariantCulture);}
}
public int endday{get;set;}
}
}

这里有一个懒惰但有效的方法。这不是目的地,而是起点

首先,将XML粘贴到网站中。它将生成一些与XML相对应的类。它并不总是完美的,但一旦它完成了,你就有了一些东西,而不是什么都没有,而且更容易调整一些东西。它给了我这个:

使用系统;
使用System.Xml.Serialization;
使用System.Collections.Generic;
名称空间Xml2CSharp
{
[XmlRoot(ElementName=“week”)]
公共课周{
[xmlement(ElementName=“groupNumber”)]
公共字符串GroupNumber{get;set;}
[xmlement(ElementName=“starttime”)]
公共字符串开始时间{get;set;}
[xmlement(ElementName=“startday”)]
公共字符串Startday{get;set;}
[xmlement(ElementName=“endtime”)]
公共字符串结束时间{get;set;}
[xmlement(ElementName=“endday”)]
公共字符串结束日{get;set;}
[xmldattribute(AttributeName=“周数”)]
公共字符串Weeknumber{get;set;}
}
[XmlRoot(ElementName=“weeks”)]
公共课周{
[xmlement(ElementName=“week”)]
公共列表周{get;set;}
}
[XmlRoot(ElementName=“root”)]
公共类根{
[xmlement(ElementName=“weeks”)]
公共周周{get;set;}
}
}
我将XML与类一起放在单元测试项目的一个文件中,并创建了这个简单的单元测试。它并不是检查所有内容,但它验证XML是否被反序列化到类的实例中,并且它是否包含三个“星期”,就像文件中一样

使用System.IO;
使用System.Xml.Serialization;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
使用Xml2CSharp;//网站创建了这个名称空间。你不需要保留它。
命名空间UnitTestProject1
{
[测试类]
公共类UnitTest1
{
[测试方法]
public void反序列化_Xml()
{
使用var stream=File.OpenText(“xmlfile1.xml”);
var serializer=新的XmlSerializer(typeof(Root));
var反序列化=(根)序列化程序。反序列化(流);
arenequal(3,反序列化的.Weeks.Week.Count);
}
}
}
那项测试通过了。我们已经渡过了难关。现在,给定一个XML文件,很容易将其读入包含所需数据的某些对象中

其他一些步骤可能是重命名类(如果您愿意的话)或更改某些类型。例如,许多这些值显然是整数,但自动生成的代码不知道这一点,所以它使用字符串。您可以更改如下属性:

public int GroupNumber{get;set;}

…现在不是字符串“1”,而是整数1

现在,给定一个类的反序列化实例,它很容易读取和操作。如果你想要周数为2的周,你可以写

IEnumerable weeksWithWeekNumberTwo=
反序列化的.Weeks.Week.Where(w=>w.Weeknumber==2);
您可以创建更多变量,但可能不需要。您可以这样做:

foreach(一周内的var周,周数为WO)
{
//每次循环执行“week”变量时
//具有所有属性。您可以将它们分配给更多
//变量,但一个带有属性的变量(“周”)更容易。
}

这种方法的一个好处是
void Main()
{
    const string fileName = @"e:\Temp\Weeks.xml";
    XDocument xdoc = XDocument.Load(fileName);
    
    var xelem = xdoc.Descendants("week")
        .Where(x => x.Attribute("weeknumber").Value.Equals("2"))
        .FirstOrDefault();

    int groupNumber = Convert.ToInt32(xelem.Element("groupNumber").Value);
    string starTtime = xelem.Element("starttime").Value;
    int startDay = Convert.ToInt32(xelem.Element("startday").Value);
    string endTime = xelem.Element("endtime").Value;
    int endDay = Convert.ToInt32(xelem.Element("endday").Value);
    
    Console.WriteLine("groupNumber={0}, starTtime={1}, startDay={2}, endTime={3}, endDay={4}", groupNumber
        , starTtime
        , startDay
        , endTime
        , endDay);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication
{
    public class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        public static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(Root));
            Root root = (Root)serializer.Deserialize(reader);
        }
    }
    [XmlRoot("root")]
    public class Root
    {
        [XmlArray("weeks")]
        [XmlArrayItem("week")]
        public List<Week> week { get; set; }
    }
    public class Week
    {
        public int groupNumber { get; set; }

        private DateTime _starttime { get; set; }
        public string starttime 
        {
            get {return _starttime.ToString("HH:mm");}
            set { _starttime = DateTime.ParseExact(value, "HH:mm", System.Globalization.CultureInfo.InvariantCulture); } 
        }
        public int startday { get; set; }
        private DateTime _endtime { get; set; }
        public string endtime
        {
            get { return _endtime.ToString("HH:mm"); }
            set { _endtime = DateTime.ParseExact(value, "HH:mm", System.Globalization.CultureInfo.InvariantCulture); }
        }
        public int endday { get; set; }
    }

}