没有 Unicode 字节顺序标记。无法切换到 Unicode

Posted

技术标签:

【中文标题】没有 Unicode 字节顺序标记。无法切换到 Unicode【英文标题】:There is no Unicode byte order mark. Cannot switch to Unicode 【发布时间】:2015-07-07 01:41:30 【问题描述】:

我正在用 XSD 编写一个 XML 验证器。

以下是我所做的,但是当验证器到达while (list.Read()) 行时,它给了我错误

谁能帮我解决?

public class Validator
    
        public void Validate(string xmlString)
        
            Boolean bRet = true;
            string xmlPath = @"C:\x.xml";
            string xsdPath = @"C:\general.xsd";

            XmlReaderSettings Settings = new XmlReaderSettings();
            Settings.Schemas.Add("", xsdPath);
            Settings.ValidationType = ValidationType.Schema;
            Settings.ValidationEventHandler += 
               new ValidationEventHandler(SettingsValidationEventHandler);

            XmlReader list = XmlReader.Create(xmlPath, Settings);
            //StringBuilder output = new StringBuilder();
            while (list.Read()) 
            
            
            //File.WriteAllText(@"D:\Output.xml", output.ToString());
        
        static void SettingsValidationEventHandler(object sender,
                                                   ValidationEventArgs e)
        
            if (e.Severity == XmlSeverityType.Warning)
            
                MessageBox.Show( "WARNING: ");
                MessageBox.Show(e.Message);
            
            else if (e.Severity == XmlSeverityType.Error)
            
                MessageBox.Show("ERROR: ");
                MessageBox.Show(e.Message);
            
        
    

XML

<?xml version="1.0" encoding="utf-16"?>
<FlashList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" vin="xxxxxxxxxxxxx">
  <flash ECUtype="xxx" />
</FlashList>

XSD

<?xml version="1.0" encoding="utf-16"?>
<xs:schema attributeFormDefault="unqualified" 
           elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="FlashList">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="flash" maxOccurs="unbounded" minOccurs="0">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute type="xs:string" name="ECUtype" use="optional"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
        <xs:element name="Error" maxOccurs="unbounded" minOccurs="0">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute type="xs:byte" name="code" use="optional" />
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
      <xs:attribute type="xs:string" name="vin"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

【问题讨论】:

您确定“物理”文件 x.xml 已正确编码吗?使用 Sublime 或 jEdit 等文本编辑器打开它,以检查实际编码。 是的,我已经在服务器端使用来自同一个 xsd 文件的 c# 生成的类制作了这个 XML 文件,并且格式正确。此代码在客户端,我只想在客户端也使用相同的 xsd 验证收到的 xml 文件 【参考方案1】:

您文件的实际编码似乎与您的 XML 声明所指定的相冲突。例如,如果您的文件实际上使用一字节字符,则声明 encoding="utf-16" 不会将其更改为使用二字节字符。

尝试从 XML 声明中删除冲突的编码。替换

<?xml version="1.0" encoding="utf-16"?>

<?xml version="1.0"?>

您也可以使用 LoadXML() 将文件加载到字符串中。

【讨论】:

FWIW: &lt;?xml version="1.0" encoding="utf-8"?&gt; 也可以解决问题。 是的,因为utf-8 是默认编码。 遇到类似错误后,这个答案帮助我解决了自己的问题。就我而言,我首先以编程方式创建 xml,然后在稍后对其进行读写。如果要使用xmlwriter 删除/更改处理指令中的编码版本,请使用writer.WriteProcessingInstruction("xml", "version='1.0'");writerXmlWriter 的一个实例)。见msdn doc 解决方法“您也可以使用 LoadXML() 将文件加载到字符串中作为解决方法。”为我工作。 但问题是解决方法是否可以安全实施?【参考方案2】:

如果您无法将 xml 文件编码更改为

<?xml version="1.0"?>

或者,您可以直接读取 xml 内容作为原始 xml 而不是加载它 使用 xml 路径。

XmlReader.Create(new StringReader(File.ReadAllText(fileName)));

如果你使用XmlDocument;

var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(File.ReadAllText(filePath));

【讨论】:

不要使用File.ReadAllText。始终创建StreamReaderFileStream。永远不要在内存中分配文件大小的块。 @Mr.TA 如果它是一个已知的小文件,比如设置或任何 File.ReadAllText 都可以。【参考方案3】:

当您在 XML 头中声明使用 UTF-16 编码但物理上不以这种编码保存此文件时,会引发此错误。

您可以使用简单的Windows记事本进行检查,点击另存为,然后在底部检查xml文件的编码(可能仍然是UTF-8,而不是UTF-16)。

Screenshot of notepad encoding setting

【讨论】:

以上是关于没有 Unicode 字节顺序标记。无法切换到 Unicode的主要内容,如果未能解决你的问题,请参考以下文章

字节顺序标记——BOM,Byte Order Mark

刨根究底字符编码之十一——UTF-8编码方式与字节序标记

BOM

如何在 Java 中编写 3 个字节的 unicode 文字?

php无bom和有bom的文件编码有啥区别

编写没有字节顺序标记 (BOM) 的文本文件?