2016-06-27 9 views
0

Я пытаюсь научиться использовать xml-файлы в своем приложении. Я хочу сделать простое чтение элемента и, возможно, переписать элемент и получить его значение. У меня есть файл XML, который выглядит примерно так:читать и писать простой элемент в xml

<?xml version="1.0" encoding="utf-16"?> 
<PTH> 
    <Account> 
    <Username>aa</Username> 
    <Password>xx</Password> 
    <Email>[email protected]</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> 

где будет только один элемент учетной записи и несколько элементов 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; 
    } 

код работает, но, кажется, на самом деле, действительно извилистый путь только для чтения значения элемента. Кроме того, я не совсем уверен, как могу, скажем, переписать только значение элемента электронной почты. У кого-нибудь есть простой способ прочитать и/или переписать значение элемента? Похоже, он должен быть очень простым, но он ускользает от меня ...

+0

если есть только 1 узел 'Account', почему' foreach' и Linq? Я думаю, вы можете использовать XPath и просто выбирать отдельные узлы для получения своих значений (InnerText). [Ссылка] (https://msdn.microsoft.com/en-us/library/h0hw012b (v = vs.110) .aspx) – zgood

+0

Да, «foreach» кажется излишним, но это то, что я нашел в уроки, которые я читал. Большинство учебников показывают простые XML-файлы только с одним типом основных элементов, таких как «книга», а не с файлами с несколькими типами элементов. – SteveFerg

+0

У вас есть контроль над XML-форматом? Если элементы были обернуты родителем , это было бы сериализуемо. – Derpy

ответ

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 = "[email protected]"; 

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

Если вы хотите еще больше Shorthands, вы можете посмотреть на This answer о том, как использовать XPath syntax (ответ немного устарели, что пространство имен теперь использовать это using System.Xml.XPath;

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> 
+0

Это дает мне еще один способ взглянуть на него. Когда я начну смотреть на астрологические диаграммы, большинство чтения/записи будет в названиях диаграмм. Я смотрю на запись функций утилиты, необходимых для обработки, поэтому это решение весьма полезно. Спасибо. – SteveFerg

Смежные вопросы