XML编码的问题

本文关键字:问题 编码 XML | 更新日期: 2023-09-27 18:14:38

我试图把这个问题作为一个通用的问题,但意识到我知道的不够,所以这就是我遇到的问题。

下面是一个控制台应用程序的代码片段:
public void Run()
{
    Run(Console.Out);
}
public void Run(TextWriter writer)
{
    DataTable customers = _quickBooksAdapter.GetTableData("Customer");
    customers.WriteXml(writer);
}

然后我从控制台中运行它,并使用">"将其放入文件中。

c:'> QuickBooksETL extract US > qb_us.xml

如果我尝试像往常一样加载结果:

var x = XDocument.Load("qb_us.xml");

我得到错误:

Invalid character in the given encoding. Line 8, position 26.

所以我试图确定。net"认为"它正在使用:

string path = @"''ad1'accounting$'Xml'qb_us.xml"; 
StreamReader sr = new StreamReader(path);
sr.CurrentEncoding.Dump();
结果:

System.Text.UTF8Encoding 
BodyName utf-8
EncodingName Unicode (UTF-8)
HeaderName utf-8
WebName utf-8
WindowsCodePage 1200
IsBrowserDisplay True
IsBrowserSave True
IsMailNewsDisplay True
IsMailNewsSave True
IsSingleByte False
EncoderFallback 5EncoderReplacementFallback  
System.Text.EncoderReplacementFallback 
DefaultString �
MaxCharCount 1
DecoderFallback 5DecoderReplacementFallback  
System.Text.DecoderReplacementFallback 
DefaultString �
MaxCharCount 1
IsReadOnly True
CodePage 65001

最后,我通过猜测发现,如果我明确地说它是ASCII,它就能工作:

string path = @"''ad1'accounting$'Xml'qb_us.xml"; 
StreamReader sr = new StreamReader(path, Encoding.ASCII);
var x = XDocument.Load(sr);

任何关于我哪里错了的想法将非常感激。我承认我从未对字符编码进行过"深入研究",但我愿意付出努力把它做好。

XML编码的问题

简单的答案是让控制台参与进来。从代码中直接写入文件:

public void Run(string filename)
{
    DataTable customers = _quickBooksAdapter.GetTableData("Customer");
    customers.WriteXml(filename);
}

或者自己创建TextWriterStream并传入,例如

public void Run(Stream output)
{
    DataTable customers = _quickBooksAdapter.GetTableData("Customer");
    customers.WriteXml(output);
}

请注意,通过将其读取为ASCII,您基本上会为原始数据中的任何非ASCII字符获得问号。IIRC,这是编码在遇到无法处理的二进制数据时的默认行为。

使用Stream,它应该默认以UTF-8格式输出,并且XML声明和文件中的数据应该匹配。

根据我的经验,如果您的数据包含非法字符(例如,字符12),除非您使用Normalization = falseXmlTextReader读取XML,否则XML不会往返。我一直在使用XmlSerializer.Deserialize(),而不是XDocument.Load()。尽管如此,您可以尝试通过传入Normalization = falseXmlTextReader来调用Load(XmlReader)重载。

我同意Jon的意见,建议你写你自己的流,而不是Console.Out