2013-07-27 4 views
0

Ok я есть файл Xml так:XML десериализации в списке

<?xml version="1.0" encoding="utf-8" ?> 
<Books> 
    <Book> 
    <Name>book name</Name> 
    <Url>book url</Url> 
    <Genre>book genre</Genre> 
    <City>book city</City> 
    <Country>book country</Country> 
    </Book> 
    <Book> 
    <Name>book name</Name> 
    <Url>book url</Url> 
    <Genre>book genre</Genre> 
    <City>book city</City> 
    <Country>book country</Country> 
    </Book> 
    <Book> 
    <Name>book name</Name> 
    <Url>book url</Url> 
    <Genre>book genre</Genre> 
    <City>book city</City> 
    <Country>book country</Country> 
    </Book> 
</Books> 

И я хочу использовать Deserialization для того, чтобы заполнить List с книгами. У меня есть класс, как это:

[Serializable] 
public class Book 
{ 
    public string Name{get; set;} 
    public string Url { get; set; } 
    public string Genre { get; set; } 
    public string City { get; set; } 
    public string Country { get; set; } 
} 

И в List вроде этого:

List<Book> BookList; 

Я пытаюсь читать из XML-файла, как это:

XmlSerializer serializer = new XmlSerializer(typeof(Book)); 
FileStream fs = new FileStream(@"Book.xml", FileMode.Open); 

using (XmlReader reader = XmlReader.Create(fs)) 
{ 
    BookList.Add((Book)serializer.Deserialize(reader)); 
    reader.Close(); 
} 

Но я получаю ошибка в Xml-файле всякий раз, когда я запускаю свое приложение. Если я изменю свой xml-файл на это:

<Book> 
    <Name>book name</Name> 
    <Url>book url</Url> 
    <Genre>book genre</Genre> 
    <City>book city</City> 
    <Country>book country</Country> 
</Book> 

все идет нормально, ожидайте, что я прочитал только 1 книгу. Я хочу читать около 100 книг. Есть идеи?

ответ

0

Вместо загрузки с FileStream, что мы можем прочитать из XmlDataDocument и итераций книжного элемента даст нам сериализация намного проще. Пожалуйста, ознакомьтесь с измененным подходом.

List<Book> BookList = new List<Book>(); 

      XmlDataDocument objDocument = new XmlDataDocument(); 
      objDocument.Load(@"Book.xml"); 


      XmlSerializer serializer = new XmlSerializer(typeof(Book));     

      foreach(XmlNode objItem in objDocument.DocumentElement.ChildNodes) 
      { 
       TextReader objTextReader = new StringReader(objItem.OuterXml); 

       using (XmlReader reader = XmlReader.Create(objTextReader)) 
        { 
         BookList.Add((Book)serializer.Deserialize(reader)); 
         reader.Close(); 
        } 
      } 
1

Вам нужно создать класс, который будет содержит список книг и seriazlie этого класса:

[Serializable] 
public class BookData 
{ 
    [XmlArray(ElementName="Books")] 
    [XmlArrayItem(ElementName="Book")] 
    public List<Book> Books {get; set;} 

} 

, а затем создать сериалайзер так:

var serializer = new XmlSerializer(typeof(BookData)); 
4

, если вы измените свой код десериализации немного, это сработает.

(См использование XmlRootAttribute & и типа Book[])

XmlSerializer serializer = new XmlSerializer(typeof(Book[]),new XmlRootAttribute("Books")); 
FileStream fs = new FileStream(@"Book.xml", FileMode.Open); 

using (XmlReader reader = XmlReader.Create(fs)) 
{ 
    var books = (Book[])serializer.Deserialize(reader); 
} 

КСТАТИ: вам не нужно Serializable атрибут, он используется только BinaryFormatter

PS: Вы можете также используйте тип List<Book> вместо Book[]

EDIT

После модифицирования коды немного больше, он может быть столь же просто, как:

XmlSerializer serializer = new XmlSerializer(typeof(List<Book>), 
               new XmlRootAttribute("Books")); 

using (FileStream fs = new FileStream(@"Book.xml", FileMode.Open)) 
{ 
    List<Book> books = (List<Book>)serializer.Deserialize(fs); 
} 
+0

Следует отметить, что код @ I4V исправляет также проблему, с которой OP_w сталкивается еще дальше из-за инструкции 'read.Close();' инструкция внутри using. –

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