[定義:如果一個數據對象滿足本規范中格式正確的之定義時,它是一個 XML 文件。一個格式正確的 XML 文件可以更進一步是有效的,如果它滿足某些進一步的約束的話。]
每一個 XML 文件都有邏輯和物理結構。物理上而言,文件由稱為實體的單元組成。一個實體可以引用(refer)其他實體,將它們包含在文件中。文件開始於"根(root)"或文件實體。邏輯上而言,文件由聲明,元素,注釋,字符引用和處理指令組成,所有這些都在文件中用顯式標記指明。邏輯和物理結構必須如"4.3.2 格式正確的已析實體"中所描述的那樣嚴格地嵌套。
[定義:一個文本對象是一個格式正確的 XML 文件如果它滿足:]
document
產生式。
document
::= prolog element Misc*
匹配 document
產生式意味著:
[定義:這樣做的結果是,對於每一個非根的元素 C
,文件中另有一個元素 P
,C
在 P
的內容中,而不在其他任何被 P
所包含的元素的內容中。P
被稱為 C
的父元素(parent),而 C
被稱為 P
的子元素(child)。]
[定義:一個已析實體包含文本(text),文本是一個字符(character)序列,可以表示標記或字符數據。] [定義:一個字符是 ISO/IEC 10646 [ISO/IEC 10646](或 [ISO/IEC 10646-2000])中定義的文本最小單元。合法的字符包括制表符,回車,換行以及 Unicode 和 ISO/IEC 10646 中定義的合法字符。在制定本文檔時,在附錄 A.1 正式參考文獻中引用的標准都是當時的最新版本,在這些標准的增補版或新版中可能會加入新的字符。因此,XML 處理器必須能接受產生式 Char 中所定義范圍內的任意字符。不提倡使用 [Unicode] 6.8 節(或 [Unicode3] 3.6 節 D21 )中定義的"兼容字符(compatibility characters)"。]
Char
::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
/* 除了代用塊(surrogate block),FFFE 和 FFFF 以外的任意 Unicode 字符。*/
將字符代碼編碼成位模式的機制各個實體間可能會有所不同。所有的 XML 處理器必須接受 10646 中的 UTF-8 和 UTF-16 編碼;用於指出所用編碼或指定使用其他編碼的機制在後面的"4.3.3 實體中的字符編碼"中討論。
本節中定義了一些在文法中廣泛使用的符號。
S
(空白)包括一個或多個空格字符(#x20),回車,換行和制表符。
S
::= (#x20 | #x9 | #xD | #xA)+
為方便起見,字符被分為字母,數字和其他字符三類。字母可以是字母表中的字母,或是一個音節基字符(syllabic base character),也可以是一個表意字符。在"B. 字符的分類"中給出了每一類字符的完整定義。
[定義:名字(name)是以字母或某些標點符號開頭的記號,後跟字母,數字,連字符,下劃線,冒號或句號,這些符號統稱為命名字符(name character)。] 以 "XML
" 或其他任何匹配 (('X'|'x') ('M'|'m') ('L'|'l'))
的字符串開頭的名字,被保留用於本規范的此版本或後續版本的標准化。
注:
建議 XML 中的名字空間 [XML Names] 中賦予了包含冒號的名字某種含義。因此除非用於名字空間,XML 文件作者不應該在 XML 名字中使用冒號,但 XML 處理器應該接受冒號作為一個命名字符。
Nmtoken
(名字記號,name token)是任何命名字符的混合體。
NameChar
::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
[5] Name
::= (Letter | '_' | ':') (NameChar)*
[6] Names
::= Name (S Name)*
[7] Nmtoken
::= (NameChar)+
[8] Nmtokens
::= Nmtoken (S Nmtoken)*
常量數據是任何用引號括起的字符串,不包括用作定界符的引號。常量用於指明內部實體的內容(EntityValue
),屬性值(AttValue
),以及外部標識符(SystemLiteral
)。注意,對 SystemLiteral
的語法分析可以不掃描標記。
EntityValue
::= '"' ([^%&"] | PEReference | Reference)* '"'
| "'" ([^%&'] | PEReference | Reference)* "'"
[10] AttValue
::= '"' ([^<&"] | Reference)* '"'
| "'" ([^<&'] | Reference)* "'"
[11] SystemLiteral
::= ('"' [^"]* '"') | ("'" [^']* "'")
[12] PubidLiteral
::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
[13] PubidChar
::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
注:
雖然產生式 EntityValue 允許定義只包含單個 <
的實體(如,),但是強烈建議避免這種用法,因為對此實體的任何引用都會引起一個格式正確性錯誤。
文本由字符數據和標記混合構成。[定義:標記包括起始標簽,結束標簽,空元素標簽,實體引用,字符引用,注釋,CDATA 段定界符,文件類型聲明,處理指令,XML 聲明,文本聲明,以及任何在文件實體頂層的空白(即,在文件元素之外且不在任何其他的標記中)。]
[定義:其他所有非標記的文本組成文件的字符數據。]
"and"號(&)和左尖括號(<)只有作為標記定界符,或在注釋,處理指令,或 CDATA 段中時才能以常量形式出現。如果在其他地方需要用到這兩個字符,它們必須用數值式字符引用來轉義或分別用字符串"&
"和"<
"表示。右尖括號(>)可以用">
"表示,而當它在內容中的字符串"]]>
"中出現,但此字符串不表示一個 CDATA 段的結束時,出於兼容性考慮,必須用">
"或一個字符引用轉義得到。
在一個元素的內容中,字符數據可以是不包括任何標記的起始定界符的任意字符串。在一個 CDATA 段中,字符數據可以是不包括 CDATA 段結束定界符"]]>
"的任意字符串。
為了允許在屬性值中包含單引號和雙引號,省略符或稱單引號(')可以被表示為"'
",而雙引號(")可以被表示為""
"。
[14] CharData
::= [^<&]* - ([^<&]* ']]>' [^<&]*)
[定義:注釋可以在其他標記之外的文件中的任何位置出現。另外,它們可以在文件類型聲明中文法允許的地方出現。它們不是文件字符數據的一部分,XML 處理器可以,但不是必須,允許一個應用檢索注釋的文本。出於兼容性考慮,字符串"--
"(雙連字符)不能在注釋中出現。] 注釋中的參數實體不被識別。
[15] Comment
::= ''
注釋的一個例子:
注意,此文法不允許注釋以 --->
結尾。下面的例子不是格式正確的。
[定義:處理指令(PI)允許文件中包含由應用來處理的指令。]
[16] PI
::= '' PITarget
(S (Char* - (Char*
'?>' Char*)))?
'?>'
[17] PITarget
::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
PI 不是文件字符數據的一部分,但必須傳遞給應用。PI 以用於指示傳遞給哪個應用的目標(PITarget
)開頭。目標名字 "XML
","XML
",等等,保留用於本規范的此版本或後續版本的標准化。XML 記法機制可以用於 PI 目標的形式化聲明。參數實體在處理指令中不被識別。
[定義:CDATA 段可以出現在字符數據可以出現的任何地方,它們用於轉義包含會被識別為標記的字符串的文本塊。CDATA 段以字符串 "" 開始,以字符串 "
]]>
" 結束:]
[18] CDSect
::= CDStart CData CDEnd
[19] CDStart
::= ' [20]
CData
::= (Char* - (Char* ']]>' Char*))
[21] CDEnd
::= ']]>'
在一個 CDATA 段內,只有 CDEnd
字符串被識別為標記,因此左尖括號和"&"可以以它們的常量形式出現,不需要(也不能)被換碼為"<
"和"&
"。CDATA 段不能嵌套。
一個 CDATA 段的例子,其中"
"和""被識別為字符數據,而不是標記:
Hello, world!]]>
[定義:XML 文件應該以一個 XML 聲明開始,其中指明了所用 XML 的版本。] 例如,以下是一個完整的 XML 文件,它是格式正確的,但不是有效的:
下面這個也同樣:
版本號 "1.0
" 應該用於表明與本規范的本版本相一致,如果使用了值 "1.0
" 但又與本規范的本版本不一致,那麼這是文件的一個錯誤。XML 工作組打算賦予本規范的後續版本不同於 "1.0
" 的數值,但這並不代表開發後續版本的承諾,也不代表如果有後續版本,會使用任何特殊的命名方案的承諾。因為不排除有後續版本的可能性,提供了本構造(construct)作為一旦需要時進行自動版本識別的手段。當處理器收到的文件標有它們不支持的版本時,可以給出一個錯誤。
XML 文件中標記的功能是描述文件的存儲格式和邏輯結構,並將屬性-值對和邏輯結構關聯起來。XML 提供一種稱為文件類型聲明的機制,用於定義對邏輯結構的約束,支持預定義存儲單元的使用。[定義:如果一個 XML 文件有相應的文件類型聲明並且它遵循其中的約束,則稱它是有效的(valid)。]
文件類型聲明必須位於文件第一個元素之前。
[22] prolog
::= XMLDecl? Misc* (doctypedecl Misc*)?
[23] XMLDecl
::= ''
[24] VersionInfo
::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')/* */
[25] Eq
::= S? '=' S?
[26] VersionNum
::= ([a-zA-Z0-9_.:] | '-')+
[27] Misc
::= Comment | PI | S
[定義:XML 文件類型聲明包含或指向標記聲明,標記聲明提供某一類文件的文法。這種文法被稱為文件類型定義(document type difinition,DTD)。文件類型定義可以指向一個外部子集(一種特殊類型的外部實體),或者可以在一個內部子集中直接包含標記聲明,或者兩者兼用。一個文件的文件類型定義由這兩個子集合在一起組成。]
[定義:標記聲明可以是元素類型聲明,屬性表聲明,實體聲明,或是記法聲明。] 這些聲明可以如下面格式正確性和有效性約束中所述,全部或部分地包含在參數實體中,"4. 物理結構"中有更多的信息。
[28] doctypedecl
::= ' [VC: 根元素類型] [WFC: 外部子集] /* */ [28a]
DeclSep
::= PEReference | S
[WFC: 聲明間的參數實體] /* */ [29] markupdecl
::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment
[VC: 嚴格的聲明/參數實體嵌套] [WFC: 內部子集中的參數實體]
注意,要構建包含了一個既不指向外部子集也不包含內部子集的 doctypedecl 而格式正確的文件是可能的。
標記聲明可以全部或部分地由參數實體的置換文本組成。本規范後面的各個非終結符(elementdecl
,AttlistDecl
,等等)產生式描述的是在所有的參數實體被包含(include)之後的聲明。
除了在常量,處理指令,注釋和被忽略的條件段的內容中出現的參數實體引用以外,DTD 中的其他任何地方(內部或外部子集以及外部參數實體)的參數實體引用都被識別(見 3.4 條件段)。在實體值常量中的參數實體引用也被識別。內部子集中參數實體引用的使用限制如下所述。
有效性約束: 根元素類型(Root Element Type) 文件類型聲明中的 Name
必須匹配根元素的類型。
有效性約束: 嚴格的聲明/參數實體嵌套 參數實體的置換文本必須用標記聲明嚴格嵌套。即,如果一個標記聲明(上面的 markupdecl
)的第一個或最後一個字符被包含於一個參數實體引用的置換文本中,兩者必須都在此置換文本中。
格式正確性約束: 內部子集中的參數實體
在內部 DTD 子集中,參數實體引用只能出現在標記聲明可以出現的地方,而不能在標記聲明內部出現。(這個約束不適用於出現在外部參數實體內的引用,也不適用於外部子集。)
格式正確性約束: 外部子集
外部子集(如果有的話)必須匹配產生式 extSubset。
格式正確性約束: 聲明間的參數實體
一個 Hello,&nb 內的參數實體引用的置換文本必須匹配產生式 extSubsetDecl。
同內部子集一樣,外部子集和任何 DeclSep 中引用的外部參數實體,必須由一系列被非終結符 markupdecl
所允許的完整的標記聲明組成,其中可以夾雜空白字符或參數實體引用。但是,外部子集和外部參數實體的部分內容可以通過使用條件段(conditional section)被有條件地忽略,在內部子集中則不允許這麼做。
[30] extSubset
::= TextDecl? extSubsetDecl
[31] extSubsetDecl
::= ( markupdecl | conditionalSect | DeclSep)*
/* */
外部子集和外部參數實體與內部實體不同之處還在於:在它們內,參數實體引用不僅可以出現在標記聲明間,還可以出現在標記聲明內。
有文件類型聲明的 XML 文件的例子:
系統標識符 "hello.dtd
" 給出了此文件的 DTD 的地址(一個 URI 引用)。
聲明也可以如同下面這個例子一樣直接(locally)給出:
]>
如果同時使用外部和內部子集,子集子集被看成出現在外部子集之前,這意味著內部子集中的實體和屬性表聲明的優先級要比在外部子集中的高。
當文件從 XML 處理器遞給應用時,標記聲明可以影響它的內容,屬性缺省值和實體聲明是其中的例子。可以作為 XML 聲明一個成分的獨立文件聲明,指明了是否存在著在文件實體外或在參數實體中的聲明。[定義:外部標記聲明被定義為出現在外部子集或參數實體(外部或內部,包括內部參數實體是因為並不強制不進行驗證的處理器讀取其中的標記聲明)中的標記聲明。]
[32] SDDecl
::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'))
[VC: 獨立文件聲明]
在一個獨立文件聲明中,值 "yes
" 表示對於文件實體沒有外部標記聲明(不論是在 DTD 外部子集中,還是在由內部實體引用的外部參數實體中)會影響從 XML 處理器傳遞給應用的信息。值 "no
" 表示有或可能有這樣的外部標記聲明。注意,獨立文件聲明只是表示外部聲明的存在,如果文件中存在對外部實體的引用,而這些實體已在內部聲明時,不影響它的獨立狀態。
如果不存在外部標記聲明,獨立文件聲明沒有意義。如果存在外部標記聲明,但沒有獨立文件聲明,就假定取值 "no
"。
某些網絡傳輸應用也許需要獨立的文件,任何滿足 standalone="no"
的 XML 文件可以通過一定的算法轉換為獨立文件。
有效性約束: 獨立文件聲明 獨立文件聲明必須取值為 "no
",如果任何外部標記聲明中包含:
amp
,lt
,gt
,apos
,quot
外的)實體的聲明,而對這些實體的引用出現在文件中的話。
具有獨立文件聲明的 XML 聲明的例子:
在編輯 XML 文件時,使用"空白"(空格,制表符,空行)來分開標記以獲得更好的可讀性是很方便的。通常在文件的交付版本中不想包含這些空白。另一方面,必須保留在交付版本中的有意義的空白是很常見的,如在詩歌和源碼中的空白。
XML 處理器必須始終把不是標記的所有字符傳遞給應用。 一個進行驗證的 XML 處理器必須同時通知應用這些字符中的那一些組成了出現在元素型內容中的空白。
可以在元素中附加一個名為 XML:space
的特殊屬性,以通知應用應該保留此元素中的空白。在有效的文件中,此屬性和其他屬性一樣,使用時必須聲明。它必須被聲明為枚舉類型,可以取值 "default
" 和 "preserve
" 兩者之一,也可以兩個都取。例如:
"default
" 表示可以對此元素使用應用的缺省空白處理模式,"preserve
" 表示應用應該保留所有的空白。這適用於其所處元素的內容中的所有元素,除非被另一個 XML:space
屬性的實例所覆蓋。
任何文件的根元素被認為對應用的空白處理方式不作要求,除非它給此屬性賦了值或將此屬性聲明為帶缺省值。
為編輯的方便起見,存儲 XML 已析實體的計算機文件經常用行來組織。通常這些行用回車符(#xD)和換行符(#xA)的一些組合來分隔。
為了使應用的工作簡單化,XML 處理器應在將字符傳給應用前,將外部已析實體(包括文件實體)中的兩字符序列 "#xD#xA" 或沒有尾隨 #xA 的 #xD 在進行語法分析前轉換成單個 #xA 字符。
在進行文件處理時,標識出其內容所使用的自然或形式化語言經常是很有用的。可以在文件中插入一個名為 XML:lang
的特殊屬性用於指出 XML 文件中任何元素的內容和屬性所使用的語言。在有效的文件中,此屬性和其他屬性一樣,使用時必須聲明。此屬性的值是 [IETF RFC 1766],Tags for the Identification of Languages 或其後的 ITEF 標准中定義的語言標識符。
注:
[IETF RFC 1766] 中的標簽由 [ISO 639] 中定義的兩字母語言碼和 [ISO 3166] 中定義的兩字母國家碼構成,或者由 Internet Assigned Numbers Authority [IANA-LANGCODES] 注冊的語言標識符構成。 預計 [IETF RFC 1766] 的後繼標准將會引入三字母語言碼用於表示 [ISO 639] 中沒有涉及的語言。
(產生式 33 到 38 已被刪除。)
舉例如下:
內的參數實體引觲idth="100%" bgcolor="#80FFFF">
The quick brown fox jumps over the lazy dog.
What colour is it?
What color is it?
XML:lang
所表示的語言選擇適用於它所處元素的所有屬性和內容,除非被此內容中的元素內的另一個 XML:lang
的實例所覆蓋。
XML:lang
的一個簡單聲明可以采用如下形式:
XML:lang NMTOKEN #IMPLIED
但是如果合適的話,也可以給出特定的缺省值。在一本供英國學生使用的法文詩歌集中,評注和注解使用英語,XML:lang 屬性可以這樣聲明: