Naga Sindhura Ответов: 1

Ошибка преобразования десериализации Xml: существует ошибка в XML-документе (2, 2)


How do I Deserialize the following xml into object. I could not recognize the mistake that I am doing and I getting the "There is an error in XML document (2, 2)" error. Could you please help me on this.


Input Xml format i.e. books.xml


<?xml version="1.0" encoding="utf-8"?>
<catalog xmlns="http://library.by/catalog" date="2016-02-05">
  <book id="bk101">
    <isbn>0-596-00103-7</isbn>
    <author>Löwy, Juval</author>
    <title>COM and .NET Component Services</title>
    <genre>Computer</genre>
    <publisher>O'Reilly</publisher>
    <publish_date>2001-09-01</publish_date>
    <description>
      COM & .NET Component Services provides both traditional COM programmers and new .NET
      component developers with the information they need to begin developing applications that take full advantage of COM+ services.
      This book focuses on COM+ services, including support for transactions, queued components, events, concurrency management, and security
    </description>
    <registration_date>2016-01-05</registration_date>
  </book>
  <book id="bk109">
    <author>Kress, Peter</author>
    <title>Paradox Lost</title>
    <genre>Science Fiction</genre>
    <publisher>R & D</publisher>
    <publish_date>2000-11-02</publish_date>
    <description>
      After an inadvertant trip through a Heisenberg
      Uncertainty Device, James Salway discovers the problems
      of being quantum.
    </description>
    <registration_date>2016-01-05</registration_date>
  </book>
</catalog>


Here are the classes:


using System;
using System.Xml.Serialization;

namespace Seralization
{
    [Serializable()]
    public class Book
    {
        [XmlAttribute("id")]
        public string BookId { get; set; }

        [XmlElement("isbn")]
        public string Isbn { get; set; }

        [XmlElement("author")]
        public string Author { get; set; }

        [XmlElement("title")]
        public string Title { get; set; }

        [XmlElement("publisher")]
        public string Publisher { get; set; }

        [XmlElement("publish_date")]
        public DateTime PublishDate { get; set; }

        [XmlElement("description")]
        public string Description { get; set; }

        [XmlElement("registration_date")]
        public DateTime RegisteredDate { get; set; }

        [XmlIgnore]
        public Genre Genre;

        [XmlAttribute("genre")]
        public string GenreValue
        {
            get { return Genre.ToString(); }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    Genre = default(Genre);
                }
                else
                {
                    Genre = (Genre)Enum.Parse(typeof(Genre), value);
                }
            }
        }
    }
}


using System;
using System.Xml.Serialization;

namespace Seralization
{
    [Serializable()]
    [XmlRoot("catalog")]
    public class Calalog
    {
        [XmlAttribute]
        public DateTime createdDate;

        [XmlArray("catalog")]
        [XmlArrayItem("book", typeof(Book))]
        public Book[] Books { get; set; }
    }
}

using System.ComponentModel;

namespace Seralization
{
    public enum Genre
    {
        Computer = 1,
        Fantasy = 2,
        Romance = 3,
        Horror = 4,
        [Description("Science Fiction")]
        ScienceFiction = 5
    }
}


Что я уже пробовал:

using System;
using System.IO;
using System.Xml.Serialization;

class Program
    {
        static void Main(string[] args)
        {
            Calalog cars = null;
            string path = @"C:\input\books.xml";

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

            StreamReader reader = new StreamReader(path);
            cars = (Calalog)serializer.Deserialize(reader);
            Console.WriteLine(cars.Books.GetType());
            reader.Close();
            Console.ReadLine();
        }
}

1 Ответов

Рейтинг:
7

FranzBe

1) Ну, если вы посмотрите во внутреннее исключение, то увидите, что пространство имен xml неизвестно

2) чтобы справиться с этим, я бы сначала построил допустимый объект, затем сериализовал его и посмотрел, как выглядит допустимая сериализованная структура. Базовый класс, который выполняет сериализацию и десериализацию, может помочь вам в этом.

2.а)

public abstract class PersistentSettingsBase<T>
{
	public string XMLSerialize()
	{
		XmlSerializer serializer = new XmlSerializer(this.GetType());
		using (StringWriter myStream = new StringWriter())
		{
			serializer.Serialize(myStream, this);
			myStream.Flush();
			return (myStream.ToString());
		}
	}

	public static T XMLDeserialize(string xmlString)
	{
		if (string.IsNullOrEmpty(xmlString))
		{
			throw new ArgumentNullException("xmlString");
		}

		XmlSerializer serializer = new XmlSerializer(typeof(T));
		using (StringReader myStream = new StringReader(xmlString))
		{
			try
			{
				return (T)serializer.Deserialize(myStream);
			}
			catch (Exception ex)
			{
				// The serialization error messages are cryptic at best. Give a hint at what
				// happended
				throw new InvalidOperationException("Failed to create object from xml string", ex);
			}
		}
	}
}



2.б)

[Serializable()]
[XmlRoot("catalog")]
public class Calalog : PersistentSettingsBase<Calalog>
{


кстати, "калалог" - это опечатка или что?


2.с)

void Main()
{		
	Calalog cars = null;
    cars = new Calalog();
	cars.createdDate = DateTime.Now;
	var b1 = new Book();
	b1.BookId = "bk101";
	b1.Title = "COM and .NET Component Services";
	b1.Isbn = "0-596-00103-7";
	b1.Genre = Genre.Computer;
	var b2 = new Book();
	b2.BookId = "bk109";
	b2.Title = "Paradox Lost";
	b2.Isbn = "not set";
	b2.Author = "Kress, Peter";
	b2.Genre = Genre.ScienceFiction;
	cars.Books = new[] { b1, b2 };
	
	string serializedCatalog = cars.XMLSerialize();
	
	Calalog deserializedCatalog = Calalog.XMLDeserialize(serializedCatalog);
    //deserializedCatalog.Dump(); // this is a linqpad command

    //your code starts here
	string path = @"C:\temp\books.xml";
	XmlSerializer serializer = new XmlSerializer(typeof(Calalog));
	StreamReader reader = new StreamReader(path);
	cars = (Calalog)serializer.Deserialize(reader);
	Console.WriteLine(cars.Books.GetType());
	reader.Close();
	Console.ReadLine();
}


Теперь у вас есть рабочее XML-представление и вы можете сравнить его с вашим, которое еще не работает. Вы увидите, что вы закодировали жанр как XMLElement в файле, однако как XmlAttribute в вашем коде (есть и другие различия).

2.д обновление:)

Если вы не можете изменить структуру данного xml-файла, вам необходимо
измените определение класса каталога

[Serializable()]
[XmlRoot(ElementName = "catalog", Namespace = "http://library.by/catalog")]
public class Catalog : PersistentSettingsBase<Catalog>
{
	[XmlAttribute]
	public DateTime date;

	[XmlElement("book")]
	public Book[] Books { get; set; }
}


DateTime в XML-файле имеет имя атрибута "date", а не" createdDate", параметр пространства имен в корневом атрибуте позволяет избежать ошибки, которую вы получаете при чтении этой части.
Вы все равно получите ошибку с "научной фантастикой", потому что ваш код не прилагает никаких усилий, чтобы использовать атрибут описания для преобразования. Я не знаю, как с этим справиться.


Naga Sindhura

Привет Францбе,
Когда я сериализую объявленный объект, а затем Десериализую его, он работает так, как ожидалось. Тем не менее, я изменил код следующим образом, но все равно получаю ту же ошибку @ "return (T)serializer.Десериализация (myStream); " линия.

путь к строке = @"C:\temp\books.xml";
StreamReader reader = новый StreamReader (путь);
строка s = reader. ReadToEnd();
читатель.Закрывать();

Каталог deserializedCatalog1 = каталог.XMLDeserialize(s);

Вместе с тем, я исправил Жанр свойство отображает.

Naga Sindhura

"xmlns="http://library.by/catalog-это на русском языке. Повлияет ли это на мой код?

FranzBe

Привет Нага он посмотреть 2.D) выше. Надеюсь, это поможет.
Существует также проблема с амперсандом в ваших данных, вам нужно удалить его, чтобы заставить его работать. вы можете посмотреть здесь:
http://stackoverflow.com/questions/1744046/deserialize-xml-with-ampersand-using-xmlserializer