企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# javascript快速入门24--XML基础 ## XML简介 XML代表Extensible Markup Language(eXtensible Markup Language的缩写,意为可扩展的标记语言)。XML 被设计用来传输和存储数据。XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。 ### XML特点 * 标记需要自己去创建!一个最大的特殊处(与HTML不同处),它可以创建标签,包括使用中文标签 * 语法更严格!标签必需成对嵌套,并且属性必须有属性值,属性值也必须包含在引号中 * XML仅仅用来存储数据,不包含与数据显示相关的样式信息(这部分信息可以通过CSS等语言来传递),XML是具有语义的 ## 书写XML 一个完整的XML必须包含XML声明与一个文档根元素!XML声明必须包含版本信息,文档根元素可以是空元素,但一个XML文档只能有一个根元素! ``` <?xml version="1.0"?> <root /> ``` **注意:XML目前存在1.0与1.1两个版本,但浏览器只支持1.0版. XML声明的version属性是必须的. XML声明之前不能有任何东西,比如空格及注释(XML注释和HTML注释是一样的).XML文档只能且必须包含一个根元素,当元素是空元素时需要闭合** XML声明还有其它两个属性:standalone与encoding.encoding属性用来指明XML文档所使用的字符编码,如指定为gbk或gb2312则可以使用中文本,standalone属性指明XML文档是否独立不依赖于外部文档,默认值是yes,当使用外部XML DTD时需要将这个属性设为no ## 格式良好的XML与有效的XML 格式良好的XML(Well-formed XML)是指文档格式符合XML语法规范的XML,解释器在解释一个Not Well-formed XML的时会出现错误而停止! 一个遵守XML语法规则,并遵守相应DTD文件规范的XML文档称为有效的XML文档(Valid XML)。注意我们比较"Well-formed XML"和"Valid XML",它们最大的差别在于一个完全遵守XML规范,一个则有自己的"文件类型定义(DTD)"。 将XML文档和它的DTD文件进行比较分析,看是否符合DTD规则的过程叫validation(确认)。这样的过程通常我们是通过一个名为parser的软件来处理的。 ## DTD——文档类型定义(Document Type Definition) 由于XML可以自定义标签,那么自然各人编写的标签不一样,这样同步数据便成了问题,因为其它人不知道某个标签应该怎么用,表示什么意思.DTD就是为了解决此问题的! DTD是一种保证XML文档格式正确的有效方法,可以比较XML文档和DTD文件来看文档是否符合规范,元素和标签使用是否正确。一个DTD文档包含:元素的定义规则,元素间关系的定义规则,元素可使用的属性,可使用的实体或符号规则。 DTD分为内部DTD与外部DTD,内部DTD包含在XML文档中,外部DTD则通过URL引用.一个DTD文件是以.dtd结尾的文本文件 ### 在XML中引入DTD DOCTYPE 文档类型声明 内部DTD,可以将standalone设置成yes. ``` <?xml version="1.0" standalone="yes"?> <!DOCTYPE root [ <!ELEMENT root EMPTY> ]> ``` 外部DTD,需要将standalone设成no ``` <?xml version="1.0" standalone="no"?> <!DOCTYPE root SYSTEM "http://www.test.org/test.dtd"> ``` ### DOCTYPE分析 DTD声明始终以!DOCTYPE开头,空一格后跟着文档根元素的名称,如果是内部DTD,则再空一格出现[],在中括号中是文档类型定义的内容. 而对于外部DTD,则又分为私有DTD与公共DTD,私有DTD使用SYSTEM表示,接着是外部DTD的URL. 而公共DTD则使用PUBLIC,接着是DTD公共名称,接着是DTD的URL.下面是一些示例 公共DTD,DTD名称格式为"注册//组织//类型 标签//语言","注册"指示组织是否由国际标准化组织(ISO)注册,+表示是,-表示不是."组织"即组织名称,如:W3C; "类型"一般是DTD,"标签"是指定公开文本描述,即对所引用的公开文本的唯一描述性名称,后面可附带版本号。最后"语言"是DTD语言的ISO 639语言标识符,如:EN表示英文,ZH表示中文,在下面的地址有完整的ISO 639语言标识符列表[http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt](http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt) ``` <!DOCTYPE root SYSTEM "http://www.test.org/test.dtd"> ``` 下面是XHTML 1.0 Transitional的DTD.以!DOCTYPE开始,html是文档根元素名称,PUBLIC表示是公共DTD,后面是DTD名称,以-开头表示是非ISO组织 组织名称是W3C,EN表示DTD语言是英语,最后是DTD的URL ``` <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml/DTD/xhtml1-transitional.dtd"> ``` ## **注意:虽然DTD的文件URL可以使用相对URL也可以使用绝对URL,但推荐标准是使用绝对URL.另一方面,对于公共DTD,如果解释器能够识别其名称,则不去查看URL上的DTD文件** ### 开始编写DTD #### XML 文档构建模块 所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成: * 元素 , 元素即所说的自定义标签,它是 XML 以及 HTML 文档的主要构建模块。 * 属性 , 属性可提供有关元素的额外信息。属性总是被置于某元素的开始标签中。属性总是以名称/值的形式成对出现的。 * 实体 , 实体是用来定义普通文本的变量。实体引用是对实体的引用。如HTML文档中的&nbsp;即是一个实体引用当文档被 XML 解析器解析时,实体就会被展开。 * PCDATA , PCDATA 的意思是被解析的字符数据(parsed character data)。可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。PDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开。不过,被解析的字符数据不应当包含任何&、&lt; 或者 &gt; 字符;需要使用 &amp;、&lt; 以及 &gt; 实体来分别替换它们。 * CDATA , CDATA 的意思是字符数据(character data)。CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。 #### CDATA PCDATA是指会被解析的字符串,这解析是指将其中的实体引用换成对应的实体内容.也就是说,一般的XML中的文本节点都是PCDATA,当这些文本中要包含一些XML特殊字符时,需要使用实体引用,当这些字符很少时,使用实体引用还不是很麻烦,而当特殊字符很多时,则需要使用CDATA,即不解析字符串. CDATA 区段开始于 "&lt;![CDATA[",结束于 "]]&gt;",CDATA段中可以包含除CDATA限定符之外的任何字符 #### 元素声明 元素声明使用&lt;!ELEMENT 元素名称 (元素内容)&gt;或&lt;!ELEMENT 元素名称 类别&gt;的语法 ``` <!ELEMENT root EMPTY> //EMPTY关键字表示元素是个空元素 <!ELEMENT root ANY> //ANY关键字表示元素中可以出现任何内容,也可以为空 //下面这个声明表示root中可以有文本,也可以是空 <!ELEMENT root (#PCDATA)> //()表示一个分组,其中是放的允许在元素出现的内容,#PCDATA表示文本 <!ELEMENT root (child)> //child是子元素的名称,这个声明表示root中必须且只能有一个child元素 <!ELEMENT root (child1,child2)> //以逗号分隔,表示子元素依次出现 <!ELEMENT root (child1|child2)> //竖线与"OR"的意思相近,表示root元素中只能出现child1或child2 <!ELEMENT root (child?)> //root中child子元素可以出现一次,也可以不出现 <!ELEMENT root (child+)> //root中child子元素至少出现一次 <!ELEMENT root (child*)> //root中child子元素可以出现任意次数或不出现 <!ELEMENT root (child,(a,b))> //()还可以嵌套,这里表示root元素中第一次子元素必须是child //紧接着是a或b <!ELEMENT root (child,(a,b)+)> //*,?,+这些量词可作用于分组,这里表示root元素中第一次子元素必须是child //紧接着是a或b出现一次或多次 <![CDATA[ ABC-abc-ABC><&;&//这个不并被替换成&吧 ]]> ``` #### 属性声明 属性声明使用&lt;!ATTLIST 元素名称 属性名称 属性类型 默认值&gt;的语法.示例如下: ``` <!ATTLIST input type CDATA "text"> ``` 上面的属性声明表示:元素input的type属性值是文本,默认值是text; 以下是属性类型表 | 类型 | 描述 | | --- | --- | | CDATA | 值为字符数据 (character data) | | (en1&#124;en2&#124;..) | 此值是枚举列表中的一个值 | | ID | 值为唯一的 id | | IDREF | 值为另外一个元素的 id | | IDREFS | 值为其他 id 的列表 | | NMTOKEN | 值为合法的 XML 名称 | | NMTOKENS | 值为合法的 XML 名称的列表 | | ENTITY | 值是一个实体 | | ENTITIES | 值是一个实体列表 | | NOTATION | 此值是符号的名称 | | xml: | 值是一个预定义的 XML 值 | 默认值参数可以使用下列值 | 值 | 解释 | | --- | --- | | 值 | 属性的默认值.该属性可以出现,也可以不出现,当没有明确指定该属性时,属性值使用默认值 | | #REQUIRED | 属性值是必需的 | | #IMPLIED | 属性不是必需的,可以出现,可以不出现 | | #FIXED value | 属性值是固定的.属性可有可无,但有的时候,其值必须是value | ``` <!ATTLIST img src CDATA #REQUIRED> //img元素的src属性是必须的,值为字符串 <!ATTLIST script type CDATA "text/javascript"> //script元素的type属性默认值是text/javascript <!ATTLIST div id ID #IMPLIED> //div元素的id属性是唯一的ID标识,可有可无 <!ATTLIST input type(text|radio|checkbox) "text"> //input元素的type属性是三个值中的一个,默认值是text <!ATTLIST label for IDREF #IMPLIED> //label元素的for属性是页面中另一个元素的ID ``` #### 实体声明 ##### 一般实体 实体是用于定义用于定义引用普通文本或特殊字符的快捷方式的变量。实体引用是对实体的引用。实体可在内部或外部进行声明。 一个内部实体是以&lt;!ENTITY 实体名称 "实体的值"&gt;的形式声明的,一个外部私有实体是以&lt;!ENTITY 实体名称 SYSTEM "URI/URL"&gt;格式声明 ,一个外部公共实体是以 &lt;!ENTITY 实体名称 PUBLIC "公共实体名称" "URI/URL"&gt; ,其中公共实体名称和DOCTYPE中的公共DTD名称格式是一样的. 一个实体引用是&实体名称;格式 ``` //实体定义 <!ENTITY abc "ABCabcABC"> //内部实体 <!ENTITY abc SYSTEM "abc.ent"> //外部私有实体 <!ENTITY test PUBLIC "-//AjaxLife//ENTITIES TEST 1 for XML//EN" "test.ent"> //外部公共实体 //实体引用 <abc>&abc;</abc> ``` ##### 参数实体 参数实体是只在DTD中使用的实体(并且参数实体只能在外部DTD中声明),它的声明语法与一般实体不同处在于其要在实体名称前加个百分号,而引用时则使用%实体名称;的形式 ``` <!ENTITY % abc "root"> <!ELEMENT %abc; (child)>//这句将声明元素root,具有一个子元素child ``` ### XML 命名空间 XML 命名空间可提供避免元素命名冲突的方法。由于 XML 中的元素名是预定义的,当两个不同的文档使用相同的元素名时,就会发生命名冲突。命名空间其实就是给这些标签名加个前缀! ``` <root> <svg:template /> <xsl:template /> </root> ``` 现在,root下仍然是两个template元素,它们的节点名称仍然是template,但是它们的意义不一样了,因为它们使用了不同的前缀!但是XML命名空间前缀需要声明才可以使用,如果不声明,则被视为元素名称的一部分! XML 命名空间属性被放置于某个元素的开始标签之中,并使用以下的语法:xmlns:namespace-prefix="namespaceURI" . 当一个命名空间被定义在某个元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联。 注意,用于标示命名空间的地址不会被解析器用于查找信息。其惟一的作用是赋予命名空间一个惟一的名称。不过,很多公司常常会作为指针来使用命名空间指向某个实存的网页,这个网页包含着有关命名空间的信息。 ``` <root xmlns:svg="http://www.svg.org" xmlns:xsl="http://www.xsl.org"> <svg:template /> <xsl:template /> </root> ``` 这样,为了区分那些名称相同而含义不同的元素,必须在每个元素名前面加前缀.其实还可以在父级元素上声明默认命名空间,让所有没有前缀子元素的默认使用此命名空间.HTML的命名空间便是一个例子. ``` <html xmlns="http://www.w3.org/1999/xhtml"> </html> ``` ## **对于使用命名空间的XML文档,其DTD中对元素的声明也应该包含命名空间前缀(即应与文档中所书写的一致).另外,命名空间不但作用于元素,还作用于属性**