有效的XML文件是否需要XML声明?


122

我正在使用Xerces的Sax解析器解析XML文件。
是否<?xml version="1.0" encoding="UTF-8"?>需要XML声明?


3
有效文件和格式正确的文件有所不同。您是哪一个?
菲利克斯·克林

我收到序言错误/无效的utf-8编码。然后我在XML文件中找到BOM,用户可以使用记事本打开该文件(我无法避免)。我不确定我是指有效的还是格式正确的文件。只是需要避免错误,这就是为什么我要创建一个删除“ <”之前的所有字节的函数的原因。我需要确保需要xml标头声明。你们觉得怎么样?
eros

是否有一个Java类可以删除BOM?或xml文件中的几个字节?从InputStream。我在想从FilterInputStream和PushbackInputStream跳过方法,但不知道如何使用它。
eros

@eros:“ 我不确定我是指有效的还是格式正确的文档 ”有关差异的简要说明,请参见格式正确与有效XML
kjhughes 2014年

Answers:


184

在XML 1.0中,XML声明可选的。请参阅XML 1.0 Recommendation的2.8节,其中说“应该”使用-这意味着它是推荐的,但不是强制性的。但是,在XML 1.1中,声明是强制性的。请参阅XML 1.1 Recommendation的2.8节,其中说“必须”。它甚至继续声明,如果不存在该声明,则自动暗示该文档是XML 1.0文档。

注意,在XML声明中encoding和和standalone都是可选的。只有version是强制性的。此外,这些也不是属性,因此,如果存在,则它们必须按以下顺序:version,后跟any encoding,然后跟随any standalone

<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" standalone="yes"?>
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>

如果您未以这种方式指定编码,则XML解析器将尝试猜测正在使用哪种编码。XML 1.0建议书描述了一种可以自动检测字符编码的可能方式。实际上,如果输入被编码为UTF-8,UTF-16或US-ASCII,这并不是什么大问题。当自动检测遇到使用US-ASCII范围之外的字符的8位编码(例如ISO 8859-1)时,自动检测将不起作用-如果可以,请避免创建这些字符。

standalone指示是否将XML文档可被正确地处理,而不DTD或没有。人们很少使用它。如今,设计一种缺少DTD而缺少信息的XML格式是一件很糟糕的事情。

更新:

“序言错误/无效的utf-8编码”错误表示解析器在文件内找到的实际数据与XML声明所声明的编码不匹配。或者在某些情况下,文件内的数据与自动检测到的编码不匹配。

由于您的文件包含字节顺序标记(BOM),因此应采用UTF-16编码。我怀疑您的声明中说<?xml version="1.0" encoding="UTF-8"?>,当NotePad将文件更改为UTF-16时,这显然是不正确的。简单的解决方案是删除encoding并简单地说<?xml version="1.0"?>。您也可以对其进行编辑以说,encoding="UTF-16"但这对于原始文件(不是UTF-16中的文件)或如果文件以某种方式变回UTF-8或其他某种编码的方式将是错误的。

不要费心尝试删除BOM,这不是问题的原因。使用NotePad或WordPad编辑XML是真正的问题!


我的问题已回答,但我的后续问题未解决。我是否需要为此提出另一个问题?或请在此处添加。
eros

5
BOM可能是问题的原因。一些较旧的XML解析器在UTF-8文档的开头不接受BOM(它是为UTF-16设计的,后来才被UTF-8接受)。但是,如果您使用的是Xerces的最新版本,则不太可能出现问题。
Michael Kay

另请注意,在记事本的“另存为”对话框中,您可以选择将XML另存为的编码。如果要删除BOM,只需另存为“ ASCII”(假设您未使用任何Unicode字符)。对于较低的127个字符,ASCII和UTF-8相同。
BrainSlugs83 2013年

8

Xml声明是可选的,因此没有它的xml格式正确。但是建议使用它,以使解析器不会做出错误的假设,特别是关于所使用的编码。


3
我是唯一发现您告诉XML解析器在开始解码您的文档后要使用哪种编码的方法的吗?我的意思是很清楚,如果它可以解析该标签并理解其含义,则说明它已经找到了正确的编码。我想不出编码属性的任何合法用途。
BrainSlugs83 2013年

2
@ BrainSlugs83在没有BOM的情况下,编码指定为8位。因此,可以使用ASCII或UTF-8或任何旧的8位国家/地区编码。XML声明全部为下半8位,在所有这些编码中均相等,并且传达了足够的信息以选择上半部分。这不是最好的设计,但是比起老式的文本文件,在CP1241和CP866之间进行猜测还是要好得多。
Eugene Ryabtsev

但是他们应该弄清楚,并说XML是UTF-8-故事的结尾。
Lothar

3

如果你不使用默认值时才需要versionencoding(你是在该示例)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.