您的位置:首页 > 运维架构 > Shell

读XML in a Nutshell (2)

2006-06-10 16:08 281 查看
本篇内容包括chapter 3 Document Type Definition。DTD用于对XML进行验证,作为SGML的代替品,早期XML主要用于描述narrative-oriented document(相对于此的文档类型为data-oriented document,前者最终将被转换成某种格式而为人所阅读,如:html,docbook,后者主要作为数据被电脑处理),正因如此,DTD对于element的内容的数据类型并不提供任何的支持,而仅在attribute的值上提供了对数据类型的简单支持(对于narrative-oriented document,attribute多用来表示关于某些内容的meta information)。DTD并不管namespace是否存在,如果要同时使用DTD跟namespace,则DTD中必须对prefix,冒号或者xmlns做明确的定义。Parameter Entity对于定义可重用的DTD非常重要,通过它可以将若干份DTD结合起来同时使用,同时也可以重新定义已经存在的DTD中的内容。

1.DTD Declaration,有以下几种定义方式,其中person指定root element的类型:
<!DOCTYPE person SYSTEM "http://www.cafeconleche.org/dtds/person.dtd">

<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN"
"http://my.netscape.com/publish/formats/rss-0.91.dtd">

<!DOCTYPE person [
<!ELEMENT first_name (#PCDATA)>
<!ELEMENT last_name (#PCDATA)>
<!ELEMENT profession (#PCDATA)>
<!ELEMENT name (first_name, last_name)>
]>

<!DOCTYPE person SYSTEM "name.dtd" [
<!ELEMENT profession (#PCDATA)>
<!ELEMENT person (name, profession*)>
]>

其中第二种使用public id,如果无法通过public id获得dtd,将从备用url中读出。第四种则是内部跟外部dtd混合使用。

2.Element,定义方式为:
<!ELEMENT element_name content_specification>

对于content specification,有如下几种定义方式:
#PCDATA:<!ELEMENT phone_number (#PCDATA)>
child element:<!ELEMENT fax (phone_number)>
sequences:<!ELEMENT name (first_name, last_name)> (在DTD中顺序出现的Element在XML中也必须按照相同的顺序出现)
the number of children:<!ELEMENT name (first_name+, middle_name?, last_name*)>
choices:<!ELEMENT methodResponse (params | fault)>
parentheses:<!ELEMENT circle (center, (radius | diameter))>
mixed content:<!ELEMENT definition (#PCDATA | term)*>
empty elements:<!ELEMENT image EMPTY>
any:<!ELEMENT page ANY>

3.Attribute,定义方式如下:
<!ATTLIST element_name (attribute_name attribute_type attribute_default)+>

有以下几种attribute name:
CDATA:任意字符串
NMTOKEN:比xml name稍微宽松的字符串规定,所有可用的字符都可做开头。
NMTOKENS:用空格隔开的若干个NMTOKEN
enumeration:枚举,必须由xml name组成,如:<!ATTLIST date month (January | February | March | April | May | June| July | August | September | October | November | December) #REQUIRED>
ID:必须是xml name
IDREF:值必须与某个存在的ID相同
IDREFS:用空格隔开的若干个IDREF
ENTITY:必须是某个已经定义的unparsed entity,如:<!ATTLIST movie source ENTITY #REQUIRED> <movie source="X-Men-trailer"/>
ENTITIES:用空格隔开的若干个ENTITY,如:<slide_show slides="slide1 slide2 slide3 slide4 slide5 slide6 slide7 slide8 slide9 slide10"/>
NOTATION:如:<!ATTLIST image type NOTATION (gif | tiff | jpeg | png) #REQUIRED>

有以下几种attribute default,#IMPLIED #REQUIRED #FIXED,其中,fixed的定义如下,由fixed标识的attribute可以被省略,如果出现,则必须与定义的值相同。
<!ATTLIST biography xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">

4.Entity,可以看成是C++里面的宏,通过entity可以将可重用部分抽象出来,在各个不同的地方使用。需要注意的是,如果entity在element的内容中被引用,则他必须能使最终生成的XML是well formed。同时,entity的内容中可以引用其他的entity,但不能由循环引用。在XML中或是DTD的默认值中使用的entity必须用&xxx;标识,而在DTD中使用%xxx;标识。包括以下几种不同类型的entity:

General entity:
<!ENTITY super "supercalifragilisticexpialidocious">

<!ENTITY footer '<hr size="1" noshade="true"/>
<font CLASS="footer">
<a href="index.html">O'Reilly Home</a> |
<a href="sales/bookstores/">O'Reilly Bookstores</a> |
<a href="order_new/">How to Order</a> |
<a href="oreilly/contact.html">O'Reilly Contacts</a><br>
<a href="http://international.oreilly.com/">International</a> |
<a href="oreilly/about.html">About O'Reilly</a> |
<a href="affiliates.html">Affiliated Companies</a>
</font>
<p>
<font CLASS="copy">
Copyright 2000, O'Reilly & Associates, Inc.<br/>
<a href="mailto:webmaster@oreilly.com">webmaster@oreilly.com</a>
</font>
</p>
'>

External parsed general entity:该entity指向的外部文件可以使用类似xml的标识来指明编码类型,如:
<!ENTITY footer SYSTEM "http://www.oreilly.com/boilerplate/footer.xml">

<?xml version="1.0" encoding="MacRoman"?>

External unparsed entities,其中NDATA xxx表示该entity的类型,该entity只在attribute中使用,同时不需要加上&xxx;标识。这个东东据说在真正使用时没有什么价值。
<!ENTITY turing_getting_off_bus SYSTEM "http://www.turing.org.uk/turing/pi1/bus.jpg" NDATA jpeg>

Parameter entities,在使用时,内部定义的entity可以覆盖外部定义的entity,同时,也可以直接把外部文件包含进当前文件,从而使若干份DTD同时工作,如:
<!ENTITY % residential_content "address, footage, rooms, baths">
<!ENTITY % rental_content "rent">
<!ELEMENT apartment (%residential_content;, %rental_content;)>

<!ENTITY % names SYSTEM "names.dtd">
%names;

5.NOTATION,定义了NOTATION后,所有要求xml name的但实际使用中需要用特殊符号的地方都可以用它来代替,在attribue的定义以及processing instruction的target中都可以被使用,不过据说这个也很少用,有如下定义方法:
<!NOTATION gif SYSTEM "image/gif">
<!NOTATION tex SYSTEM "/usr/local/bin/tex">

6.Conditional Inclusion,包括IGNORE跟INCLUDE两个指令,通过跟parameter entitty同时使用可以动态决定是否定义某些内容:
<![IGNORE[<!ELEMENT production_note (#PCDATA)>]]>

<![INCLUDE[<!ELEMENT production_note (#PCDATA)>]]>

<!ENTITY % notes_allowed "INCLUDE">
<![%notes_allowed;[<!ELEMENT production_note (#PCDATA)>]]>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: