C# 合并少量xml文件:编码问题
我的应用程序从web服务获取的xml文件很少,如下所示:C# 合并少量xml文件:编码问题,c#,xml,encoding,utf-8,C#,Xml,Encoding,Utf 8,我的应用程序从web服务获取的xml文件很少,如下所示: <?xml version="1.0" encoding="iso-8859-1"?> <root> <person> <!— some elements here —> </person> <person> <!— some elements here —> </person>
<?xml version="1.0" encoding="iso-8859-1"?>
<root>
<person>
<!— some elements here —>
</person>
<person>
<!— some elements here —>
</person>
</root>
var readers = files.Select(XmlReader.Create).ToList();
var writer = XmlWriter.Create("final.xml");
...
writer.WriteStartDocument();
writer.WriteStartElement("root");
foreach (var reader in readers)
{
reader.MoveToContent();
reader.Read();
while (!reader.EOF)
{
string elementName = reader.Name;
if (elementName.Equals("person", StringComparison.OrdinalIgnoreCase))
{
writer.WriteNode(reader, false);
}
else
{
reader.Read();
}
}
}
writer.WriteEndElement();
writer.WriteEndDocument();
...
//dispose all readers and writers
var readers = files.Select(x => XmlReader.Create(new StreamReader(x))).ToList();
XmlReader.Create("path/to/file.xml")
XmlReader.Create(new StreamReader("path/to/file.xml"))
它工作正常,在最后一个文件中,我有xml序言中的utf-8。但如果我创建这样的读者:
<?xml version="1.0" encoding="iso-8859-1"?>
<root>
<person>
<!— some elements here —>
</person>
<person>
<!— some elements here —>
</person>
</root>
var readers = files.Select(XmlReader.Create).ToList();
var writer = XmlWriter.Create("final.xml");
...
writer.WriteStartDocument();
writer.WriteStartElement("root");
foreach (var reader in readers)
{
reader.MoveToContent();
reader.Read();
while (!reader.EOF)
{
string elementName = reader.Name;
if (elementName.Equals("person", StringComparison.OrdinalIgnoreCase))
{
writer.WriteNode(reader, false);
}
else
{
reader.Read();
}
}
}
writer.WriteEndElement();
writer.WriteEndDocument();
...
//dispose all readers and writers
var readers = files.Select(x => XmlReader.Create(new StreamReader(x))).ToList();
XmlReader.Create("path/to/file.xml")
XmlReader.Create(new StreamReader("path/to/file.xml"))
我在xml序言中有相同的utf-8,但在最终文件中有损坏的数据。例如,我没有使用symbolå�. 我试图找出这个问题的原因,但没有结果。为什么会这样 当您像这样创建
XmlReader
时:
<?xml version="1.0" encoding="iso-8859-1"?>
<root>
<person>
<!— some elements here —>
</person>
<person>
<!— some elements here —>
</person>
</root>
var readers = files.Select(XmlReader.Create).ToList();
var writer = XmlWriter.Create("final.xml");
...
writer.WriteStartDocument();
writer.WriteStartElement("root");
foreach (var reader in readers)
{
reader.MoveToContent();
reader.Read();
while (!reader.EOF)
{
string elementName = reader.Name;
if (elementName.Equals("person", StringComparison.OrdinalIgnoreCase))
{
writer.WriteNode(reader, false);
}
else
{
reader.Read();
}
}
}
writer.WriteEndElement();
writer.WriteEndDocument();
...
//dispose all readers and writers
var readers = files.Select(x => XmlReader.Create(new StreamReader(x))).ToList();
XmlReader.Create("path/to/file.xml")
XmlReader.Create(new StreamReader("path/to/file.xml"))
然后,文件的编码将从XML声明中推断出来,因此iso-8859-1
。这显然是正确的
当您像这样创建
XmlReader
时:
<?xml version="1.0" encoding="iso-8859-1"?>
<root>
<person>
<!— some elements here —>
</person>
<person>
<!— some elements here —>
</person>
</root>
var readers = files.Select(XmlReader.Create).ToList();
var writer = XmlWriter.Create("final.xml");
...
writer.WriteStartDocument();
writer.WriteStartElement("root");
foreach (var reader in readers)
{
reader.MoveToContent();
reader.Read();
while (!reader.EOF)
{
string elementName = reader.Name;
if (elementName.Equals("person", StringComparison.OrdinalIgnoreCase))
{
writer.WriteNode(reader, false);
}
else
{
reader.Read();
}
}
}
writer.WriteEndElement();
writer.WriteEndDocument();
...
//dispose all readers and writers
var readers = files.Select(x => XmlReader.Create(new StreamReader(x))).ToList();
XmlReader.Create("path/to/file.xml")
XmlReader.Create(new StreamReader("path/to/file.xml"))
您使用的重载接受文本阅读器
。TextReader
返回unicode,因此XmlReader
不需要进行解码。结果是声明中指定的编码被完全忽略。这在以下章节中提到:
文本读取器返回Unicode字符流,因此XML读取器不使用XML声明中指定的编码来解码数据流
如果要这样做,需要为StreamReader
指定正确的编码,因为它无法正确检测到:
new StreamReader("path/to/file.xml", Encoding.GetEncoding("iso-8859-1"));
AFAIK unicode是一个字符集,utf-8/iso-8859-1是编码。在这两种情况下都使用unicode吗?错误的编码是否意味着我从二进制数据中接收到错误的数字,并且最终使用unicode字符集将这些数字解释为错误?@mtkachenko您的文件(这是一个字节负载)被解码为字符串(unicode字符),然后在您再次将其写入文件时重新编码。解码是这里的问题所在,您得到的字符是错误的,因为您的
StreamReader
使用了错误的解码器(它将默认为UTF-8,因为没有其他BOM指示)。处理:字节->基于编码的数字->基于字符集的字符串。所以第二步是错误的,最后第三步也是错误的,对吗?这里的方法错误:字节->utf-8->unicode。好方法:字节->iso-8859-1->unicode(或unicode的子集)。是吗?@mtkachenko没有中间步骤,您只是从字节->字符串再返回。所有编码都是从unicode到unicode的,因为.NET中的所有字符串都是这样。是的,但是不同的编码可以对一个符号(数字)使用不同的字节数。