我如何更改此 XML 字符串以便 XDocument.Parse 读取它?
在下面的代码中,我将一个对象序列化为 XML 字符串。
但是,当我尝试使用 XDocument.Parse 将此 XML 字符串读入 XDocument 时,它会给出以下错误:
根级别的数据无效。
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>
更新: 这是十六进制:
![alt text][1]
Mod 编辑 - 禁用的超链接:指向恶意软件的链接
< strong>我必须对此 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 + ")";
}
}
}
答案:
谢谢 Andras,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;
}
In the following code, I serialize an object into an XML string.
But when I try to read this XML string into an XDocument with XDocument.Parse, it gives me this error:
Invalid data at root level.
The XML is:
<?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: Here is the hex:
![alt text][1]
Mod edit - disabled hyperlink: links to malware
What do I have to do to this XML so that it reads into the XDocument without an error?
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 + ")";
}
}
}
ANSWER:
Thanks Andras, GetPreamble() fixed it, so for anyone else dealing with this, here is a little method to clean your XML of the BOM:
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是因为数据包含 unicode 或 utf8 BOM 标记 位于流的开头。
您需要跳过流中的任何字节顺序标记 - 您可以从 System.Text.Encoding.GetPreamble() 方法。
It's because the data contains the unicode or utf8 BOM marks at the start of the stream.
You need to skip past any Byte Order Marks in the stream - you can identify these from the System.Text.Encoding.GetPreamble() method.
您可以通过使用
StreamReader
将MemoryStream
中的数据转换为字符串来解决问题:You can resolve your problem by using a
StreamReader
to convert the data in theMemoryStream
to a string instead:以上所有内容都是正确的,您应该使用以下代码来跳过 BOM:
通过在构造函数中指定 false,您可以说“未提供 BOM”。享受! =)
All above is correct, and here is a code that you should use instead of yours to skip BOM:
By specifying false in the constructor you say "BOM is not provided". Enjoy! =)