xml的notation声明用于定义未解析实体的数据类型和关联处理器。1. 基本结构包括notation名称、system或public标识符;2. system指定外部处理器uri,如处理gif图像;3. public提供公共与系统标识符,如svg dtd;4. 使用案例包含声明notation和未解析实体,并通过ndata指定处理方式;5. notation用于扩展xml支持多种数据类型,但存在兼容与安全限制;6. 现代替代方案为xml schema,其具备更强的数据类型、命名空间和验证能力;7. xml schema使用xml语法,支持复杂结构定义,而dtd更简单但功能有限;8. 示例展示了书籍信息在dtd和xml schema中的不同定义方式;9. 总结指出xml schema是现代首选,dtd适用于旧系统兼容。

XML的notation声明语法主要用于定义XML文档中未解析实体(unparsed entities)的数据类型和关联的应用程序。它告诉XML解析器如何处理这些实体,因为解析器本身无法直接理解它们的内容。
<!NOTATION notation_name SYSTEM "system_identifier">
或者
<!NOTATION notation_name PUBLIC "public_identifier" "system_identifier">
notation声明语法的详细解释与使用案例
notation声明的基本结构
XML notation声明使用 <!NOTATION 标签开始,包含以下几个关键部分:
-
notation_name: notation的名称,必须唯一。 -
SYSTEM "system_identifier": 指向外部应用程序或处理器的系统标识符(URI)。 -
PUBLIC "public_identifier" "system_identifier": 包括公共标识符和系统标识符。公共标识符通常是注册的名称,系统标识符提供实际的URI。
SYSTEM标识符
SYSTEM 关键字后跟一个URI,告诉XML解析器使用哪个外部程序来处理相关的未解析实体。例如:
<!NOTATION gif SYSTEM "image/gif">
这表明名为 "gif" 的notation与处理GIF图像的应用程序相关联。
PUBLIC标识符
PUBLIC 关键字允许使用一个公共标识符,这通常是一个正式注册的名称。系统标识符作为备用,以防公共标识符不可用。例如:
<!NOTATION svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
这里,公共标识符是SVG 1.1 DTD的正式名称,系统标识符是DTD的URI。
使用案例
假设有一个XML文档需要嵌入一个未解析的GIF图像。首先,声明一个notation:
<!NOTATION gif SYSTEM "image/gif">
然后,在文档中声明一个未解析的实体:
<!ENTITY logo SYSTEM "images/logo.gif" NDATA gif>
NDATA gif 告诉解析器,这个实体的数据类型由名为 "gif" 的notation处理。
为什么要使用notation声明?
XML解析器本身并不理解所有类型的数据。Notation声明允许XML文档引用外部资源或程序来处理特定类型的数据,例如图像、音频或视频。这使得XML可以用于描述包含多种数据类型的复杂文档。
notation声明与DTD的关系
Notation声明通常在DTD(文档类型定义)中使用,用于定义XML文档的结构和约束。在XML Schema中,可以使用类似的功能,但语法和使用方式略有不同。
notation声明的局限性
尽管notation声明提供了一种处理未解析实体的方法,但它也有一些局限性。例如,XML解析器不一定支持所有notation,而且处理外部资源可能会带来安全风险。因此,在使用notation声明时需要谨慎。
notation声明的替代方案
在现代XML处理中,更常见的做法是使用XML Schema来定义文档结构和数据类型,并使用XSLT等技术来转换和处理XML数据。这些方法更加灵活和强大,但也更复杂。
XML Schema中的类似功能包括定义复杂类型和使用 xs:any 元素来允许包含任意内容。
一个更完整的例子
假设你需要在一个XML文档中嵌入一个PDF文件,并使用外部PDF阅读器来处理它。首先,声明一个notation:
<!NOTATION pdf SYSTEM "application/pdf">
然后,声明一个未解析的实体:
<!ENTITY report SYSTEM "reports/annual_report.pdf" NDATA pdf>
最后,在文档中使用这个实体:
<document> <title>Annual Report</title> <content>&report;</content> </document>
当XML解析器遇到 &report; 实体时,它会知道这个实体的数据类型是 "pdf",并且应该使用 application/pdf 相关的程序来处理它。
如何处理XML文档中的非法字符?
XML文档中的非法字符是指那些不符合XML规范的字符,例如某些控制字符和特殊符号。处理这些字符对于确保XML文档的有效性和可解析性至关重要。
使用字符实体引用
这是最常用和推荐的方法。XML定义了一些预定义的字符实体引用,用于表示特殊字符:
代表 <code><-
>代表> -
&代表& -
'代表' -
"代表"
例如,如果你想在XML文档中包含 > 字符,你应该使用 > 代替。
使用数字字符引用
数字字符引用允许你使用字符的Unicode值来表示字符。有两种形式:
十进制值;十六进制值;
例如,要表示字符 "A"(Unicode值为65),你可以使用 A 或 A。
CDATA Sections
CDATA sections 允许你在XML文档中包含包含大量特殊字符的文本块,而无需对每个字符进行转义。CDATA sections 以 <![CDATA[ 开始,以 ]]> 结束。
<description>
<![CDATA[
This is a CDATA section.
It can contain characters like <, >, and &.
]]>
</description>需要注意的是,CDATA sections 不能包含 ]]> 序列。
删除或替换非法字符
在某些情况下,你可能需要删除或替换非法字符。这通常在处理来自外部源的数据时发生。你可以使用编程语言中的字符串处理函数来实现这一点。
例如,在Python中,你可以使用正则表达式来删除或替换非法字符:
import re
def remove_invalid_xml_chars(text):
"""Removes invalid XML characters from a string."""
# XML 1.0 允许的字符范围
pattern = re.compile(u'[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]')
return pattern.sub('', text)
text = "This string contains an invalid character: \x01"
cleaned_text = remove_invalid_xml_chars(text)
print(cleaned_text) # 输出: This string contains an invalid character:字符编码
确保你的XML文档使用正确的字符编码,例如UTF-8。字符编码声明应位于XML文档的开头:
<?xml version="1.0" encoding="UTF-8"?>
如果字符编码不正确,XML解析器可能会无法正确解释文档中的字符。
验证XML文档
使用XML验证器可以帮助你检测XML文档中的非法字符和其他错误。有许多在线和离线XML验证器可供使用。
处理来自外部源的数据
当处理来自外部源的数据时,务必小心处理非法字符。对数据进行清洗和验证,以确保它符合XML规范。
选择合适的方法
选择哪种方法取决于你的具体需求和情况。如果只需要处理少量特殊字符,使用字符实体引用可能就足够了。如果需要处理包含大量特殊字符的文本块,CDATA sections 可能更合适。如果需要处理来自外部源的数据,可能需要删除或替换非法字符。
XML Schema与DTD有什么区别?
XML Schema和DTD(文档类型定义)都是用于定义XML文档结构的规范,但它们在功能、语法和使用方式上存在显著差异。
功能差异
- 数据类型支持: XML Schema支持丰富的数据类型,例如字符串、数字、日期等。DTD只支持字符串类型。
- 命名空间支持: XML Schema支持命名空间,允许在XML文档中使用来自不同来源的元素和属性。DTD不支持命名空间。
- 验证能力: XML Schema提供更强大的验证能力,可以验证XML文档的数据类型、结构和约束。DTD的验证能力相对有限。
- 可扩展性: XML Schema具有更好的可扩展性,可以定义复杂的文档结构和约束。DTD的可扩展性较差。
语法差异
- 语法: XML Schema使用XML语法编写,DTD使用自己的语法。
- 可读性: XML Schema的可读性更好,因为它是用XML编写的。DTD的语法相对晦涩。
- 复杂性: XML Schema的语法更复杂,但功能更强大。DTD的语法更简单,但功能有限。
使用方式差异
- 定义位置: XML Schema可以作为独立的XML文档存在,也可以嵌入到XML文档中。DTD通常作为独立的文本文件存在。
-
引用方式: XML Schema使用
xsi:schemaLocation属性在XML文档中引用。DTD使用<!DOCTYPE>声明在XML文档中引用。 - 解析器支持: 大多数现代XML解析器都支持XML Schema。对DTD的支持正在逐渐减少。
XML Schema的优势
- 更强大的数据类型支持: XML Schema可以验证XML文档中的数据类型,例如确保数字是整数,日期是有效的日期格式。
- 命名空间支持: XML Schema允许在XML文档中使用来自不同来源的元素和属性,避免命名冲突。
- 更好的可扩展性: XML Schema可以定义复杂的文档结构和约束,例如元素之间的关系、属性的取值范围等。
- 更好的可读性: XML Schema使用XML语法编写,更容易阅读和理解。
DTD的优势
- 更简单: DTD的语法更简单,更容易学习和使用。
- 更广泛的支持: 尽管对DTD的支持正在减少,但仍然有许多旧的XML解析器只支持DTD。
一个简单的例子
假设你需要定义一个XML文档,用于存储书籍的信息。
使用DTD:
<!DOCTYPE book [ <!ELEMENT book (title, author, publisher)> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT publisher (#PCDATA)> ]> <book> <title>The Lord of the Rings</title> <author>J.R.R. Tolkien</author> <publisher>Allen & Unwin</publisher> </book>
使用XML Schema:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
<xs:element name="publisher" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>XML文档:
<book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="book.xsd">
<title>The Lord of the Rings</title>
<author>J.R.R. Tolkien</author>
<publisher>Allen & Unwin</publisher>
</book>总结
XML Schema比DTD更强大、更灵活,并且是现代XML开发的首选。然而,DTD仍然在某些情况下有用,特别是当需要与旧的系统兼容时。










