从XML声明片段获取XML编码:部分内容解析不支持XmlDeclaration

我正在研究一些代码来读取包含XML声明的XML片段,例如并解析编码。 从MSDN ,我应该能够这样做:

 var nt = new NameTable(); var mgr = new XmlNamespaceManager(nt); var context = new XmlParserContext(null, mgr, null, XmlSpace.None); var reader = new System.Xml.XmlTextReader(@"", System.Xml.XmlNodeType.XmlDeclaration, context); 

但是,我在调用System.Xml.XmlTextReader构造函数时收到System.Xml.XmlTextReader并显示错误消息:

部分内容解析不支持XmlNodeType XmlDeclaration。

我用引号搜索了这个错误 – 确切地找到零结果(编辑:现在有一个结果:这篇文章) – 并且没有引号,这没有任何用处。 我也查看了MSDN的XmlNodeType ,并没有说它不受支持。

我在这里想念的是什么? 如何从XML声明片段中获取XmlTextReader实例

注意, 我的目标只是确定部分构建的XML文档的编码 ,我假设它至少包含一个声明节点; 因此,我正在努力获得reader.Encodingreader.Encoding 。 如果有另一种方法可以做到这一点,我对此持开放态度。

目前,我正在使用正则表达式手动解析声明,这不是最好的方法。

更新:从XML文档或XML片段获取编码:

这是一种使用XmlReader.Create获取编码而无需诉诸伪root的方法。

 private static string GetXmlEncoding(string xmlString) { if (string.IsNullOrWhiteSpace(xmlString)) throw new ArgumentException("The provided string value is null or empty."); using (var stringReader = new StringReader(xmlString)) { var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }; using (var xmlReader = XmlReader.Create(stringReader, settings)) { if (!xmlReader.Read()) throw new ArgumentException( "The provided XML string does not contain enough data to be valid XML (see https://msdn.microsoft.com/en-us/library/system.xml.xmlreader.read)"); var result = xmlReader.GetAttribute("encoding"); return result; } } } 

这是输出,带有完整的片段XML:

XML编码与XmlReader.Create

如果要使用System.Text.Encoding,可以将代码修改为如下所示:

  private static Encoding GetXmlEncoding(string xmlString) { using (StringReader stringReader = new StringReader(xmlString)) { var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }; var reader = XmlReader.Create(stringReader, settings); reader.Read(); var encoding = reader.GetAttribute("encoding"); var result = Encoding.GetEncoding(encoding); return result; } } 

老答案:

正如您所提到的, XmlTextReader的Encoding -property包含编码。

这是一个完整的控制台应用程序的源代码,希望是有用的:

 class Program { static void Main(string[] args) { var asciiXML = @"ToveJaniReminderDon't forget me this weekend!"; var utf8XML = @"ToveJaniReminderDon't forget me this weekend!"; var asciiResult = GetXmlEncoding(asciiXML); var utfResult = GetXmlEncoding(utf8XML); Console.WriteLine(asciiResult); Console.WriteLine(utfResult); Console.ReadLine(); } private static Encoding GetXmlEncoding(string s) { var stream = new MemoryStream(Encoding.UTF8.GetBytes(s)); using (var xmlreader = new XmlTextReader(stream)) { xmlreader.MoveToContent(); var encoding = xmlreader.Encoding; return encoding; } } } 

这是程序的输出:

XML编码输出

如果你知道XML只包含声明,也许你可以添加一个空根? 例如:

  var fragmentResult = GetXmlEncoding(xmlFragment + ""); 

XML片段

晚上好,这是使用System.Text.Encoding作为输出的解决方案。 我让它变得清晰,一步一步。

 class Program { static void Main(string[] args) { var line = File.ReadLines(YourFileName).First(); var correctXml = line + ""; var xml = XDocument.Parse(correctXml); var stringEncoding = xml.Declaration.Encoding; var encoding = System.Text.Encoding.GetEncoding(stringEncoding); } } 

也许迟到了但是你可以在XmlDocument中加载后使用下面的代码

  static string getEncoding(XmlDocument xml) { if (xml.FirstChild.NodeType == XmlNodeType.XmlDeclaration) { return (xml.FirstChild as XmlDeclaration).Encoding; } return "utf-8"; } 

如果你有一个字节数组作为输入,尝试这样的事情:

 private Encoding getEncoding(byte[] data) { XmlReaderSettings settings = new XmlReaderSettings(); settings.DtdProcessing = DtdProcessing.Ignore; XmlDocument doc = new XmlDocument(); MemoryStream ms = new MemoryStream(data); XmlReader reader = XmlReader.Create(ms, settings); doc.Load(reader); XmlDeclaration declaration = doc.ChildNodes.OfType().FirstOrDefault(); return Encoding.GetEncoding(declaration.Encoding); }