8

要加载具有任意编码的 XML 文件,我有以下代码:

Encoding encoding;
using (var reader = new XmlTextReader(filepath))
{
    reader.MoveToContent();
    encoding = reader.Encoding;
}

var settings = new XmlReaderSettings { NameTable = new NameTable() };
var xmlns = new XmlNamespaceManager(settings.NameTable);
var context = new XmlParserContext(null, xmlns, "", XmlSpace.Default, 
    encoding);
using (var reader = XmlReader.Create(filepath, settings, context))
{
    return XElement.Load(reader);
}

这可行,但是两次打开文件似乎效率低下。有没有更好的方法来检测编码,这样我就可以做到:

  1. 打开文件
  2. 检测编码
  3. 将 XML 读入 XElement
  4. 关闭文件
4

2 回答 2

9

好吧,我应该早点想到这一点。XmlTextReader(它为我们提供编码)和 XmlReader.Create(它允许我们指定编码)都接受一个 Stream。那么如何首先打开一个 FileStream,然后将它与 XmlTextReader 和 XmlReader 一起使用,如下所示:

using (var txtreader = new FileStream(filepath, FileMode.Open))
{
    using (var xmlreader = new XmlTextReader(txtreader))
    {
        // Read in the encoding info
        xmlreader.MoveToContent();
        var encoding = xmlreader.Encoding;

        // Rewind to the beginning
        txtreader.Seek(0, SeekOrigin.Begin);

        var settings = new XmlReaderSettings { NameTable = new NameTable() };
        var xmlns = new XmlNamespaceManager(settings.NameTable);
        var context = new XmlParserContext(null, xmlns, "", XmlSpace.Default,
                 encoding);

        using (var reader = XmlReader.Create(txtreader, settings, context))
        {
            return XElement.Load(reader);
        }
    }
}

这就像一个魅力。以独立于编码的方式读取 XML 文件应该更优雅,但至少我只打开了一个文件。

于 2009-03-12T10:32:23.893 回答
0

另一个非常简单的选择是使用 Linq to XML。Load 方法会自动从 xml 文件中读取编码。然后,您可以使用XDeclaration.Encoding属性获取编码器值。来自 MSDN 的示例:

// Create the document
XDocument encodedDoc16 = new XDocument(
new XDeclaration("1.0", "utf-16", "yes"),
new XElement("Root", "Content")
);
encodedDoc16.Save("EncodedUtf16.xml");
Console.WriteLine("Encoding is:{0}", encodedDoc16.Declaration.Encoding);
Console.WriteLine();

// Read the document
XDocument newDoc16 = XDocument.Load("EncodedUtf16.xml");
Console.WriteLine("Encoded document:");
Console.WriteLine(File.ReadAllText("EncodedUtf16.xml"));
Console.WriteLine();
Console.WriteLine("Encoding of loaded document is:{0}", newDoc16.Declaration.Encoding);

虽然这可能不符合原始海报的要求,因为他必须重构大量代码,但对于必须为他们的项目编写新代码的人,或者如果他们认为重构是值得的,这很有用。

于 2016-04-16T01:17:50.833 回答