2010-01-15 52 views
9

在下面的代码中,我将序列化为一个对象为XML 字符串如何更改此XML字符串,以便XDocument.Parse将其读入?

但是,当我尝试读取这个XML字符串到一个XDocument与XDocument.Parse,它给了我这个错误

无效的数据在根目录下。

的XML是:

<?xml version="1.0" encoding="utf-8"?> 
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Id>1</Id> 
    <FirstName>Jim</FirstName> 
    <LastName>Jones</LastName> 
    <ZipCode>23434</ZipCode> 
</Customer> 

UPDATE:这里是十六进制:

alt text http://www.deviantsart.com/upload/hhcvmu.png

我有什么做的这个XML,以便它读入XDocument没有错误?

using System; 
using System.Collections.Generic; 
using System.Xml.Serialization; 
using System.IO; 
using System.Xml; 
using System.Text; 
using System.Xml.Linq; 

namespace TestSerialize2342 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Customer> customers = Customer.GetCustomers(); 

      Console.WriteLine("--- Serializing ------------------"); 

      foreach (var customer in customers) 
      { 
       Console.WriteLine("Serializing " + customer.GetFullName() + "..."); 
       string xml = XmlHelpers.SerializeObject<Customer>(customer); 

       XDocument xdoc = XDocument.Parse(xml); 

      } 

      Console.ReadLine(); 
     } 

    } 

    public static class StringHelpers 
    { 
     public static String UTF8ByteArrayToString(Byte[] characters) 
     { 
      UTF8Encoding encoding = new UTF8Encoding(); 
      String constructedString = encoding.GetString(characters); 
      return (constructedString); 
     } 

     public static Byte[] StringToUTF8ByteArray(String pXmlString) 
     { 
      UTF8Encoding encoding = new UTF8Encoding(); 
      Byte[] byteArray = encoding.GetBytes(pXmlString); 
      return byteArray; 
     } 
    } 

    public static class XmlHelpers 
    { 
     public static string SerializeObject<T>(object o) 
     { 
      MemoryStream ms = new MemoryStream(); 
      XmlSerializer xs = new XmlSerializer(typeof(T)); 
      XmlTextWriter xtw = new XmlTextWriter(ms, Encoding.UTF8); 
      xs.Serialize(xtw, o); 
      ms = (MemoryStream)xtw.BaseStream; 
      return StringHelpers.UTF8ByteArrayToString(ms.ToArray()); 
     } 

     public static T DeserializeObject<T>(string xml) 
     { 
      XmlSerializer xs = new XmlSerializer(typeof(T)); 
      MemoryStream ms = new MemoryStream(StringHelpers.StringToUTF8ByteArray(xml)); 
      XmlTextWriter xtw = new XmlTextWriter(ms, Encoding.UTF8); 
      return (T)xs.Deserialize(ms); 
     } 
    } 

    public class Customer 
    { 
     public int Id { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string Street { get; set; } 
     public string Location { get; set; } 
     public string ZipCode { get; set; } 

     private int internalValue = 23; 

     public static List<Customer> GetCustomers() 
     { 
      List<Customer> customers = new List<Customer>(); 
      customers.Add(new Customer { Id = 1, FirstName = "Jim", LastName = "Jones", ZipCode = "23434" }); 
      customers.Add(new Customer { Id = 2, FirstName = "Joe", LastName = "Adams", ZipCode = "12312" }); 
      customers.Add(new Customer { Id = 3, FirstName = "Jack", LastName = "Johnson", ZipCode = "23111" }); 
      customers.Add(new Customer { Id = 4, FirstName = "Angie", LastName = "Reckar", ZipCode = "54343" }); 
      customers.Add(new Customer { Id = 5, FirstName = "Henry", LastName = "Anderson", ZipCode = "16623" }); 
      return customers; 
     } 

     public string GetFullName() 
     { 
      return FirstName + " " + LastName + "(" + internalValue + ")"; 
     } 

    } 
} 

答:

感谢安德拉斯,GetPreamble()固定,所以对任何人处理这个,这里是清洁您的BOM的XML少许方法:

public static string RemoveUtf8ByteOrderMark(string xml) 
{ 
    string byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()); 
    if (xml.StartsWith(byteOrderMarkUtf8)) 
    { 
     xml = xml.Remove(0, byteOrderMarkUtf8.Length); 
    } 
    return xml; 
} 
+0

该XML没有问题。你确定这是导致异常的XML吗? – 2010-01-15 10:03:48

+0

无效数据在根级别,第1行,字符1.当我将文本复制到NotePad ++中时,第一个字符是“?”并在其他编辑器中控制一些字符... – 2010-01-15 10:03:53

+0

然后,在剪切和粘贴过程中,您丢失了打开的“<”。 XML没有问题。 – 2010-01-15 10:09:04

回答

15

这是因为数据包含流的开始处的unicode或utf8 BOM marks

您需要跳过流中的任何字节顺序标记 - 您可以使用System.Text.Encoding.GetPreamble()方法识别这些标记。

+0

在记事本中创建XML文件时,您经常遇到此问题。 VS也可以添加它们。 – 2010-01-15 10:09:48

+0

使用GetPreamble()是尝试解决后果而不是理由。请看我的答案。 – Restuta 2010-01-15 10:29:47

+0

是的,这是一个很好的答案 - 如果编码总是UTF8的话,它就可以工作。 但是,通过使用GetPreamble方法,您可以自动检测文件的编码,这意味着您不会只绑定一个文件。一旦选定,您可以调整您的代码样本以适应任何编码。 – 2010-01-15 10:51:45

1

您可以通过使用StreamReaderMemoryStream将数据转换为字符串,而不是解决问题的方法:

public static string SerializeObject<T>(object o) 
{ 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     XmlSerializer xs = new XmlSerializer(typeof(T)); 
     using (XmlWriter xtw = XmlWriter.Create(ms)) 
     { 
      xs.Serialize(xtw, o); 
      xtw.Flush(); 
      ms.Seek(0, SeekOrigin.Begin); 
      using (StreamReader reader = new StreamReader(ms)) 
      { 
       return reader.ReadToEnd(); 
      } 
     } 
    } 
} 
+0

-1:不推荐使用'XmlTextWriter'。改为使用'XmlWriter.Create'。 – 2010-01-15 10:14:09

+0

@John:编译器不会推荐使用“XmlTextWriter”的信息。我知道'XmlWriter.Create'建议,但我不想更改OP代码来解决问题。不过,更新我的代码示例以遵循建议。 – 2010-01-15 11:21:11

-1

以上所有是正确的,这里要说的是,你应该使用的,而不是你的代码跳过BOM:

public static string SerializeObject<T>(object o) 
     { 
      MemoryStream ms = new MemoryStream(); 
      XmlSerializer xs = new XmlSerializer(typeof(T)); 
      //here is my code 
      UTF8Encoding encoding = new UTF8Encoding(false); 
      XmlTextWriter xtw = new XmlTextWriter(ms, encoding); 
      //XmlTextWriter xtw = new XmlTextWriter(ms, Encoding.UTF8); 
      xs.Serialize(xtw, o); 
      ms = (MemoryStream)xtw.BaseStream; 
      return StringHelpers.UTF8ByteArrayToString(ms.ToArray()); 
     } 

通过构造函数中指定你说 “BOM不提供”。请享用! =)

+0

-1,-1,-1:您需要在'MemoryStream'和'XmlWriter'周围放置'使用'块。您不需要使用'XmlTextWriter',它已经从.NET 2.0开始被弃用了 - 而是使用'XmlWriter.Create'。 'o'参数的类型应该是'T';除此之外,这将允许您的呼叫者不指定 - 它通常会被参数的类型暗示。 – 2010-01-15 18:07:32

+0

同意,但这只是一个修改的原始代码的副本,所以它不是我的目标来审查它,并找到漏洞和设计问题。如果你会尝试阅读这个讨论,你可能会注意到我已经解决了我所要求的问题。所以先把你的“-1”拿出来。 – Restuta 2010-01-16 23:18:43

相关问题