在xml中读写一个简单的元素

时间:2016-06-27 20:52:05

标签: c# asp.net xml linq

我正在尝试学习在我的应用程序中使用xml文件。我想对元素进行简单的读取,并可选择重写元素并获取其值。我有一个类似于:

的xml文件
<?xml version="1.0" encoding="utf-16"?>
<PTH>
  <Account>
    <Username>aa</Username>
    <Password>xx</Password>
    <Email>xyz@xyz.com</Email>
    <Role>Student</Role>
  </Account>
  <ChartName>
    <Id>1</Id>
    <Name>John Smith</Name>
    <PlaceOfBirth>louisville, ky</PlaceOfBirth>
    <BirthDate>1/1/70</BirthDate>
    <TimeZone>Greenwich</TimeZone>
  </ChartName>
  <ChartName>
    <Id>2</Id>
    <Name>John Smith</Name>
    <PlaceOfBirth>New York, NY</PlaceOfBirth>
    <BirthDate>1/1/1980</BirthDate>
    <TimeZone>Greenwich</TimeZone>
  </ChartName>
  <ChartName>
    <Id>3</Id>
    <Name>Jane Doe</Name>
    <PlaceOfBirth>Los Angeles, Ca</PlaceOfBirth>
    <BirthDate>1/1/1990</BirthDate>
    <TimeZone>Greenwich</TimeZone>
  </ChartName>
</PTH>

只有一个Account元素和多个ChartName元素。我想出的代码是:

public class Account
{
    public string Username { get; set; }
    public string Password { get; set; }
    public string Email { get; set; }
    public string Role { get; set; }
}

...

    XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath("~") + "\\App_Data\\" + username.Text.Trim());
    XElement xEle = xml.Element("PTH");

    var Accounts = (from Account in xml.Root.Elements("Account")
                   select new
                   {
                       Email = (string)Account.Element("Email").Value,
                       Role = (string)Account.Element("Role").Value
                   });
    foreach (var Account in Accounts)
    {
        Session["Email"] = Account.Email;
        Session["Role"] = Account.Role;
    }

代码有效,但似乎是一种真正的,非常复杂的方式来读取元素的值。另外,我不太确定如何重写电子邮件元素值。有没有人有一种简单的方法来读取和/或重写元素值?它似乎应该是非常基本的,但它逃脱了我...

2 个答案:

答案 0 :(得分:1)

我已经为你写了这个样本。它只有6行,它可以读取和写入XML文档。

我发表的评论解释了发生了什么。

        // this loads up your XDocument.  your XDocument is an object which represents your xml file.
        XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath("~") + "\\App_Data\\" + username.Text.Trim());

        // this is a quick and dirty way to get the all of the elements element named "Email"
        // don't worry too much about "var" it's still strongly typed, and is just a syntatical shortcut so I dont' have to actually type out 
        // the name of whatever type xml.Descendant returns.
        var emails = xml.Descendants("Email");

        // if you want just one, use "First"
        var firstEmail = emails.First();

        // if you want the value, use the ".Value" property
        Console.WriteLine(firstEmail.Value);

        // if you want to change it, use normal assignment, and
        firstEmail.Value = "JohnDoe@gmail.com";

        // if you want to persist your changes to disk, save your document.
        xml.Save("C:\\temp\\otherfolder\\xmldocument.xml");

如果您想要更多的短片,可以查看This answer关于如何使用XPath syntax(答案有点过时,您现在使用的命名空间为using System.Xml.XPath;

答案 1 :(得分:1)

如果您可以控制XML格式,我发现序列化是解析XML的更文明的方法。 JSON实际上是我选择的格式,但XML也可以。如果您想稍后添加首选项属性,只需将其添加到PTH类。

    private void Test()
    {
        var obj = new PTH()
        {
            Account = new Account() { UserName = "bob's", Password = "burgers" },
            ChartNames = Enumerable.Range(1, 3).Select(x => new ChartName() { Id = x, name = "Name_" + x.ToString() }).ToArray()
        };
        var xml = SerializeXML(obj);
        var objDeserialized = DeserializeXML<PTH>(xml);
        var chartsToChange = objDeserialized.ChartNames.Where(x => x.Id == 1).ToList();
        foreach (var chart in chartsToChange)
        {
            chart.name = "new name";
        }

        var backToXML = SerializeXML(objDeserialized);
    }

    public static string SerializeXML<T>(T obj)
    {
        var izer = new System.Xml.Serialization.XmlSerializer(typeof(T));

        using (var stringWriter = new StringWriter())
        {
            using (var xmlWriter = new XmlTextWriter(stringWriter))
            {
                izer.Serialize(xmlWriter, obj);
                return stringWriter.ToString();
            }
        }
    }

    public static T DeserializeXML<T>(string xml)
    {
        var izer = new System.Xml.Serialization.XmlSerializer(typeof(T));

        using (var stringReader = new StringReader(xml))
        {
            using (var xmlReader = new XmlTextReader(stringReader))
            {
                return (T)izer.Deserialize(xmlReader);
            }
        }
    }
    public class PTH
    {
        public Account Account { get; set; }
        public ChartName[] ChartNames { get; set; }
    }
    public class Account
    {
        public string UserName { get; set; }
        public string Password { get; set; }
    }

    public class ChartName
    {
        public int Id { get; set; }
        public string name { get; set; }
    }

XML并没有太大的不同,只是数组项需要一个父节点。

<?xml version="1.0" encoding="UTF-8"?>
<PTH xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Account>
      <UserName>bob's</UserName>
      <Password>burgers</Password>
   </Account>
   <ChartNames>
      <ChartName>
         <Id>1</Id>
         <name>Name_1</name>
      </ChartName>
      <ChartName>
         <Id>2</Id>
         <name>Name_2</name>
      </ChartName>
      <ChartName>
         <Id>3</Id>
         <name>Name_3</name>
      </ChartName>
   </ChartNames>
</PTH>