Xml反序列化转换错误:XML文档中存在错误(2,2) [英] Xml deserialize conversion error: there is an error in XML document (2, 2)

查看:86
本文介绍了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
    }
}





我尝试过:





What I have tried:

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)
好​​吧,如果你调查内部异常你看到xml的命名空间是未知的



2)为了相处,我首先构建一个有效的对象,然后序列化它,看看有效的序列化结构如何好像。执行序列化和反序列化的基类可能会对此有所帮助。



2.a)



1) Well, if you look into the inner exception you see that the namespace of the xml is not known

2) To get along, I would first build a valid object, then serialize it and see how the valid serialized structure looks like. A base class that does the serialization and deserialization might help you with this.

2.a)

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.b)






2.b)

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





顺便说一句。 calalog是一个错字还是什么?





2.c)





btw. "calalog" is a typo or what?


2.c)

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表示,可以将它与你尚未运行的表示进行比较。你会看到你在文件中将Genre编码为XMLElement,但是作为代码中的XmlAttribute(还有其他差异)。



2.d,更新:)



如果您无法自由更改给定xml文件的结构,则需要

更改您的定义目录类





Now you have a working XML representation and can compare it to yours that is not yet working. You will see that you encoded Genre as an XMLElement in the file, however as an XmlAttribute in your code (there are other differences as well).

2.d, update:)

If you are not free to change the structure of the given xml-file you need to
change the definition of you Catalog class

[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; }
}





XML文件中的DateTime的属性名称为date而不是createdDate, root属性中的命名空间参数可以避免读取此部分时出现的错误。

您仍然会收到科幻小说的错误,因为您的代码不会使用Description属性进行转换。我不知道如何处理这个问题。



The DateTime in the XML-File has an attribute Name of "date" not "createdDate", the Namespace parameter in the root attribute avoids the error you get when reading this part.
You still will get an error with "Science Fiction" because your code makes no effort to use the Description attribute for conversion. I don't know how to handle this.


这篇关于Xml反序列化转换错误:XML文档中存在错误(2,2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆