在 XML DTD 中,是否可以根据同一元素是否为文档根来提供多个定义?
In XML DTDs is it possible to provide multiple definitions for same element depending on whether it will be document root or not?
例如,假设一个 XML 文件 book_list.xml
是包含 0 本书或多本书的列表视图,每本书只有 3 个子元素 id、title 和 author。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bookList SYSTEM "books.dtd">
<bookList>
<book>
<id>123</id>
<title>One Book Title</title>
<author>......</author>
</book>
<book>
<id>456</id>
<title>Another Book Title</title>
<author>......</author>
</book>
</bookList>
另一个 XML 文件 book.xml
是单本书的详细视图,其中包含许多其他必需属性,例如出版商、年份、isbn。此文档的根元素是 book
.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book SYSTEM "books.dtd">
<book>
<id>123</id>
<title>One Book Title</title>
<author>.....</author>
<isbn>......</isbn>
<year>......</year>
<publisher>......</publisher>
</book>
我的问题是我们能否在单个 DTD 中为 book
元素提供重载定义,其中 book
元素只有 3 个子元素,当它是 bookList
的子元素时 "required" 如果 book
本身是文档根,那么有许多其他子元素,还是我们必须创建单独的 DTD 文件?
不,这不可能。
当一个元素在 DTD 中定义时,它的定义将是相同的,无论您使用该元素的上下文如何,唯一的可能性是提供 book
元素的整体定义,并提供可选的标签或属性。
然而,这是您在 XML 架构中拥有的一项功能(有一些条件),您可以在其中为元素内容提供本地定义。
我认为使用 DTD 最接近此类功能的方法是使用 INCLUDE
and IGNORE
sections。
您可以创建参数实体来保存 INCLUDE/IGNORE 值。 DTD 可以设置为默认 book
声明之一。
要切换到其他 book
声明,您需要在 DOCTYPE 声明的内部子集中重新定义参数实体。
示例(使用 Xerces 在 oXygen 中验证)
books.dtd
<!ENTITY % bigbook "IGNORE">
<!ENTITY % smallbook "INCLUDE">
<!ELEMENT bookList (book)+>
<![%smallbook;[
<!ELEMENT book (id,title,author)>
]]>
<![%bigbook;[
<!ELEMENT book (id,title,author,isbn,year,publisher)>
]]>
<!ELEMENT id (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT isbn (#PCDATA)>
<!ELEMENT year (#PCDATA)>
<!ELEMENT publisher (#PCDATA)>
book_list.xml
<!DOCTYPE bookList SYSTEM "books.dtd">
<bookList>
<book>
<id>123</id>
<title>One Book Title</title>
<author>......</author>
</book>
<book>
<id>456</id>
<title>Another Book Title</title>
<author>......</author>
</book>
</bookList>
book.xml
<!DOCTYPE book SYSTEM "books.dtd" [
<!ENTITY % bigbook "INCLUDE">
<!ENTITY % smallbook "IGNORE">
]>
<book>
<id>123</id>
<title>One Book Title</title>
<author>.....</author>
<isbn>......</isbn>
<year>......</year>
<publisher>......</publisher>
</book>
例如,假设一个 XML 文件 book_list.xml
是包含 0 本书或多本书的列表视图,每本书只有 3 个子元素 id、title 和 author。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bookList SYSTEM "books.dtd">
<bookList>
<book>
<id>123</id>
<title>One Book Title</title>
<author>......</author>
</book>
<book>
<id>456</id>
<title>Another Book Title</title>
<author>......</author>
</book>
</bookList>
另一个 XML 文件 book.xml
是单本书的详细视图,其中包含许多其他必需属性,例如出版商、年份、isbn。此文档的根元素是 book
.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book SYSTEM "books.dtd">
<book>
<id>123</id>
<title>One Book Title</title>
<author>.....</author>
<isbn>......</isbn>
<year>......</year>
<publisher>......</publisher>
</book>
我的问题是我们能否在单个 DTD 中为 book
元素提供重载定义,其中 book
元素只有 3 个子元素,当它是 bookList
的子元素时 "required" 如果 book
本身是文档根,那么有许多其他子元素,还是我们必须创建单独的 DTD 文件?
不,这不可能。
当一个元素在 DTD 中定义时,它的定义将是相同的,无论您使用该元素的上下文如何,唯一的可能性是提供 book
元素的整体定义,并提供可选的标签或属性。
然而,这是您在 XML 架构中拥有的一项功能(有一些条件),您可以在其中为元素内容提供本地定义。
我认为使用 DTD 最接近此类功能的方法是使用 INCLUDE
and IGNORE
sections。
您可以创建参数实体来保存 INCLUDE/IGNORE 值。 DTD 可以设置为默认 book
声明之一。
要切换到其他 book
声明,您需要在 DOCTYPE 声明的内部子集中重新定义参数实体。
示例(使用 Xerces 在 oXygen 中验证)
books.dtd
<!ENTITY % bigbook "IGNORE">
<!ENTITY % smallbook "INCLUDE">
<!ELEMENT bookList (book)+>
<![%smallbook;[
<!ELEMENT book (id,title,author)>
]]>
<![%bigbook;[
<!ELEMENT book (id,title,author,isbn,year,publisher)>
]]>
<!ELEMENT id (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT isbn (#PCDATA)>
<!ELEMENT year (#PCDATA)>
<!ELEMENT publisher (#PCDATA)>
book_list.xml
<!DOCTYPE bookList SYSTEM "books.dtd">
<bookList>
<book>
<id>123</id>
<title>One Book Title</title>
<author>......</author>
</book>
<book>
<id>456</id>
<title>Another Book Title</title>
<author>......</author>
</book>
</bookList>
book.xml
<!DOCTYPE book SYSTEM "books.dtd" [
<!ENTITY % bigbook "INCLUDE">
<!ENTITY % smallbook "IGNORE">
]>
<book>
<id>123</id>
<title>One Book Title</title>
<author>.....</author>
<isbn>......</isbn>
<year>......</year>
<publisher>......</publisher>
</book>