XML的主要相关技术
一.XML的主要相关技术 1.处理XML的相关技术 处理XML数据时,一定要使用XML Processor(也就是XML Parser),把XML数据结构的检查等交给XML Rarser去做。关于XMLProcessor有许多软件产品,当然,也有不少事免费的。开发工程师只需要将XML数据的检查工作交给XML Processor即可,集中精力开发应用程序部分,减少了不小的负担。常用技术如DOM,SAX,JDOM以及轻量级开发包 DOM4J. 应用程序对接收XML Processor传递来的XML树进行处理,向用户提供服务。此时,不管是电子商务,还是知识管理,都是定义XML数据结构的技术、显示XML数据的技术、XML数据结构变更技术、XML数据连接整合技术、用程序操作XML树的API和其他应用技术的组合。 2.定义XML数据结构的技术 DTD和XML Schema 3.显示和打印XML数据的技术 CSS,XSLT 4.XML数据结构转换技术
二. 1.任何的XML文件有且仅有一个根元素。通常把跟在根元素下的并且是并列关系的元素称为子元素。当然,每个子元素也可以包含自己的子元素,对根元素来说就像儿子的儿子一样。 <?xml version="1.0" encoding="UTF-8" ?> <book> <title>My First XML</title> <prod id="33-657" media="paper" /> <chapter> Introduction to XML <para>What is HTML</para> <para>what is XML</para> </chapter> <charter> XML Syntax <para>Elements must have a closing tag</para> <para>Elements must be properly nested</para> </charter> </book> 2.一个XML元素可以包含不同类型的元素内容,结合以上实例,可以把元素内容类型分为以下三种: (1).混合型 混合型内容是指一个元素既有文本内容,又有嵌套元素。在以上实例中,chapter 拥有混合型内容,因为它同时拥有文本内容“Introduction to XML ”以及嵌套的元素para。 (2)简单内容 简单内容是指一个元素拥有文本内容。元素para就拥有简单内容,因为他只拥有文本内容。 (3)空内容 空内容是指一个元素不带有任何内容。元素prod就属于空内容,因为它并不携带任何内容。 3.元素的属性 一个XML元素也可以包含元素的属性,在以上实例中,只有prod元素拥有属性,id 属性值是“33-657” ,media属性值是“paper”。 XML元素属性是用于提高这个元素的额外信息的,在上面的实例中,prod 元素本身没有包含元素的值,但是包含用于描述这个元素的额外信息,即这本书的出版社的ID,以及所采用的媒介。它并不是元素的值,所以在解析的时候,这些值是不会被Java或其他的语言所提取出来的。 在属性的描述中,必须给属性值加上引号,单引号和双引号都可以。
4.结构良好的文档 语法正确 XML中有5个保留字:“”” “&” “<”“>” 以及“’” 在编写自己的XML文档时,有时会出现数据中本身就包含这几个对于解析器来说比较敏感的字段。为了不让解析器误解,XML引入实体来代替以上几个敏感保留字,当编写XML文档时就可以采用这几个实体来替换,如表所示。
三.命名空间 1.XML中采用命名空间的的目的有二: a. 解决XML文档中具有相同名称的元素和属性命名的冲突问题。 b.将来自单一XML应用的相关元素和属性集合在一起,使软件能更容易识别。 2.命名空间是用来混合多个词汇为一个单一文档的标准工具,通过在每个元素和属性的名称之间添加前缀来实现命名空间。每个前缀映射到一个URI(Uniform Resource Identifier,统一资源标识符)。还可以为元素提供默认的URI,与相同URI关联的元素和属性属于同一个命名空间。 3.命名空间的定义 xmlns属性用来命名空间的定义 命名空间为元素和属性分派URI,以消除相同名称所产生的的歧义。命名空间属性被放置于元素的开始标签之中。 命名空间的声明有两种方式:直接命名定义方式和默认命名定义方式。 l 直接命名定义方式: xmlns:[命名空间前缀]=[命名空间名URI] l 默认命名定义方式: xmlns=[命名空间名URI] 4.命名空间作用域 默认命名定义方式:?定义命名空间的元素的任何没有特殊说明的子元素以及包含在没有前缀的元素内的子元素。 直接命名定义方式:?定义命名空间的元素的子元素?除非子元素指定了其他的命名空间。默认命名定义方式声明命名空间时url可以为空?直接定义不可以?当url为空的时候表示该元素不属于任何一个命名空间。 命名空间作用于属性? 没有前缀的属性,不属于任何命名空间。若一个属性所在的元素属于某一个命名空间,并不足以让该属性本身也属于这个命名空间。唯一让一个属性归属于一个命名空间的方法是,让它有个已声明的前缀,例如xlink:type Xpath 简写方式 有些轴可以使用缩写形式,其中包括: @ 代替 attribute:: // 代替descendant-or-self::node() . 代替 self::node() .. 代替 parent::node() 无代替 child:: (如果 XPath 表达式没有给出节点,则默认使用这个轴) 如果是用星号(*),可以选择特定节点的所有孩子,如 topics/* 选择 topics 下的所有子节点
四.XML文档类型定义——DTD 1.XML DTD声明 DTD使用文档类型声明(例如:DOCTYPE)引入到XML文档结构中。文档声明放在XML文档的序言部分,以“<!DOCTYPE”开头,以“>”结束。 XML DTD 简介:文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。 DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。 1.内部的 DOCTYPE 声明 假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:***************************************************************************** <!DOCTYPE 根元素 [元素声明]> ***************************************************************************** 带有 DTD 的 XML 文档实例 ***************************************************************************** <?xmlversion="1.0"?> <!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend</body> </note> ***************************************************************************** 以上 DTD 解释如下: !DOCTYPE note (第二行)定义此文档是 note 类型的文档。 !ELEMENT note (第三行)定义 note 元素有四个元素:"to、from、heading,、body" !ELEMENT to (第四行)定义 to 元素为"#PCDATA" 类型 !ELEMENT from (第五行)定义 from 元素为"#PCDATA" 类型 !ELEMENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型 !ELEMENT body (第七行)定义 body 元素为 "#PCDATA" 类型
2.外部文档声明 假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中: <!DOCTYPE 根元素 SYSTEM|PUBLIC" 文件名及其位置"> 参数说明: ? SYSTEM:指该外部DTD文件是私有的,这个关键字主要用于引用一个作者或者组织所编写的众多XML文档中通用的DTD ? PUBLIC:指该外部DTD文件是公用的,是一个由权威机构制定的提供给特定行业和公众使用的DTD。PUBLIC DTD 都有一个逻辑名称——DTD-name,用户必须在调用时指明这个逻辑名称 ? 文件名及其位置:以URL的形式指明DTD的位置。 这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD: ***************************************************************************** <?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd"> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> 这是包含 DTD 的 "note.dtd" 文件: <!ELEMENT note (to,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ***************************************************************************** 为什么使用 DTD 通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。 通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。 而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。 您还可以使用 DTD 来验证您自身的数据。 模块 XML 以及 HTML 文档的主要构建模块是类似 <body>....</body> 这样的标签。 XML 文档构建模块 所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成: 元素 属性 实体 PCDATA CDATA实体 实体是用来定义普通文本的变量。实体引用是对实体的引用。 大多数同学都了解这个 HTML 实体引用:""。这个“无折行空格”实体在 HTML 中被用于在某个文档中插入一个额外的空格。 当文档被 XML 解析器解析时,实体就会被展开。 PCDATA PCDATA 的意思是被解析的字符数据(parsed character data)。 可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。 PDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。 文本中的标签会被当作标记来处理,而实体会被展开。 不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 & 、< 以及 > 实体来分别替换它们。 CDATA CDATA 的意思是字符数据(character data)。 CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。 元素 在一个 DTD 中,元素通过元素声明来进行声明。 声明一个元素 在 DTD 中,XML 元素通过元素声明来进行声明。元素声明使用下面的语法: <!ELEMENT 元素名称 类别> 或者 <!ELEMENT 元素名称 (元素内容)> 空元素 空元素通过类别关键词EMPTY进行声明: <!ELEMENT 元素名称 EMPTY> 只有 PCDATA 的元素 只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明: <!ELEMENT 元素名称 (#PCDATA)> 带有任何内容的元素 通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合: <!ELEMENT 元素名称 ANY> 带有子元素(序列)的元素 带有一个或多个子元素的元素通过圆括号中的子元素名进行声明: <!ELEMENT 元素名称 (子元素名称 1)> 或者 <!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)> 相同的元素至少出现一次的声明 语法格式为: <!ELEMENT element-name (child-name+)> 例: <!ELEMENT note (message+)> 例中的+是指子元素message必须在被包含的note元素里出现一次或者多次。 相同的元素不出现或者多次出现的声明 语法格式为: <!ELEMENT element-name (child-name*)> 例: <!ELEMENT note (message*)> 例中的*是指子元素message能够在被包含的note元素里不出现或者出现多次。 属性 在 DTD 中,属性通过 ATTLIST 声明来进行声明。 声明属性 属性声明拥使用下列语法: <!ATTLIST 元素名称 属性名称 属性类型 默认值>
以下是属性类型的选项: 类型 描述 CDATA 值为字符数据 (character data) (en1|en2|..) 此值是枚举列表中的一个值 ID 值为唯一的 id IDREF 值为另外一个元素的 id IDREFS 值为其他 id 的列表 NMTOKEN 值为合法的 XML 名称 NMTOKENS 值为合法的 XML 名称的列表 ENTITY 值是一个实体 ENTITIES 值是一个实体列表 NOTATION 此值是符号的名称 xml: 值是一个预定义的 XML 值 默认值参数可使用下列值: 值 解释 属性的默认值 #REQUIRED 属性值是必需的 #IMPLIED 属性不是必需的 #FIXED value 属性值是固定的 Default value 事先定义了默认值的属性。需要在DTD中提供一个默认值;在XML文档中可以为该属性提供新的属性值,也可以不另外给出属性值。 规定一个默认的属性值 DTD: <!ELEMENT square EMPTY> <!ATTLIST square width CDATA "0"> 合法的 XML: <square width="100" /> 在上面的例子中,"square" 被定义为带有 CDATA 类型的 "width" 属性的空元素。如果宽度没有被设定,其默认值为0 。 实体 实体是用于定义引用普通文本或特殊字符的快捷方式的变量。 实体引用是对实体的引用。 实体可在内部或外部进行声明。 一个内部实体声明 语法: <!ENTITY 实体名称 "实体的值"> DTD 例子: <!ENTITY writer "Bill Gates"> <!ENTITY copyright "Copyright 具体的url">XML例子: <author>&writer;©right;</author>注释: 一个实体由三部分构成: 一个和号 (&),一个实体名称,以及一个分号 (;)。 一个外部实体声明 语法: <!ENTITY 实体名称 SYSTEM "URI/URL"> DTD 例子: <!ENTITY writer SYSTEM "具体的url"> <!ENTITY copyright SYSTEM "具体的url">XML例子: <author>&writer;©right;</author>
3. 优劣
DTD的优势 每一个XML文档都可携带一个DTD,用来对该文档格式进行描述,测试该文档是否为有效的XML文档。既然DTD有外部和内部之分,当然就可以为某个独立的团体定义一个公用的外部DTD,那么多个XML文档就都可以共享使用该DTD,使得数据交换更为有效。甚至在某些文档中还可以使内部DTD和外部DTD相结合。在应用程序中也可以用某个DTD来检测接收到的数据是否符合某个标准。 对于XML文档而言,虽然DTD不是必须的,但它为文档的编制带来了方便。加强了文档标记内参数的一致性,使XML语法分析器能够确认文档。如果不使用DTD来对XML文档进行定义,那么XML语法分析器将无法对该文档进行确认。 元素的定义 根元素的声明 每个XML文档都只有一个根元素,其它的子元素都包含在该根元素中。因此在DTD中对根元素的声明是必不可少的。根元素声明的一般形式如下: <!DOCTYPE root[ <!-- 子元素 --> ]> <!-- 文件体 --> DOCTYPE是“document type”(文档类型)的简写,DOCTYPE声明必须放在文档最顶部,在所有代码和标识之上,DOCTYPE声明是必不可少的关键组成部分。DTD语法要求DOCTYPE必须要大写,而且DOCTYPE和元素之间必须要有空格隔开。如在以上代码中DOCTYPE和根元素root之间要有空格隔开。
DTD的缺陷 利用DTD验证有效性的解析器,就能够立即对文档的完整性进行可靠的检查。DTD虽然比较实用,但DTD也有不少的缺陷。 DTD有自己的特殊语法,其本身不是XML文档; DTD只提供了有限的数据类型,用户无法自定义类型; DTD不支持域名机制。
五.XML Schema 1.下面列出一个XML文档及其XSD文档,使我们对XSD有个简单的认识: XML :
<?xml version="1.0" encoding="UTF-8"?> <note xmlns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com note.xsd"> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> XSD:
<?xml version="1.0" encoding="UTF-8"?> (1) <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" (2) targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com" elementFormDefault="qualified"> <xs:element name="note"> (3) <xs:complexType> (4) <xs:sequence> (5) <xs:element name="to" type="xs:string"/> (6) <xs:element name="from" type="xs:string"/> (7) <xs:element name="heading" type="xs:string"/> (8) <xs:element name="body" type="xs:string"/> (9) </xs:sequence> </xs:complexType> </xs:element> </xs:schema> 说明如下:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com" elementFormDefault="qualified"> l<xs:schema> 是所有XSD文档的根元素,其属性描述文档的名空间及文档引用; lxmlns:xs="http://www.w3.org/2001/XMLSchema"指示使用xs:作前缀的元素、属性、类型等名称是属于http://www.w3.org/2001/XMLSchema命名空间的。同时显示schema 中用到的元素和数据类型来自命名空间 "http://www.w3.org/2001/XMLSchema" l targetNamespace="http://www.w3schools.com"指示本文档定义的元素、属性、类型等名称属于http://www.w3schools.com名空间;意思就是被此 schema 定义的元素(note,to,body) 来自命名空间:http://www.w3school.com.cn(.xml文件中使用的命名空间)。 lxmlns="http://www.w3schools.com"指示缺省的名空间是http://www. w3schools.com,即没有前缀的元素、属性、类型等名称是属于该名空间的。 l elementFormDefault=" qualified " 指示使用本 XSD 定义的 XML 文档所使用的元素必须在本文档中定义且使用名空间前缀。
2.XSD相对于 DTD的优势 (1)XSD支持数据类型; l易于描述许可的文档组成; l易于校验数据的合法性; l易于使用数据库中的数据; l易于定义数据的约束; l易于定义数据的模式; l易于在不同数据类型间进行格式转换 (2)XSD使用XML语法; (3)XSD使数据交换更安全,因为它描述了数据的格式,避免了歧义; (4)XSD可以扩展,支持类型的扩展和结构的扩展。
3.文档引用 XSD支持名空间(NameSpace)和文档引用。通过名空间,可以避免文档引用中可能导致的名称重复问题。W3C规定XSD的名空间使用URI作为名称。以前面的XML 为例:
<note xmlns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com note.xsd"> l xmlns="http://www.w3schools.com"指示本文档缺省的名空间,即没有前缀的所有的元素应在该空间中定义; l xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"指示本文档要引用http://www.w3.org/2001/XMLSchema-instance名空间定义的名称,其前缀是xsi; l xsi:schemaLocation="http://www.w3schools.com note.xsd" 指示本文档要引用的 http://www.w3schools.com 名空间的 XSD 文档是 note.xsd 。 如果要引用多个名空间的 XSD 文档,则使用空格分隔多个 ‘Namespace xs d’ 对 。例如: http://www.acom.com a.xsd http://www.bcom.com b.xsd... 。 如果 XSD 文档没有使用名空间 ,则使用 xsi:noNamespaceSchemaLocation="note.xsd" 代替 xsi:schemaLocation 。
4.简单元素描述和复杂元素 简单元素指只包含text的XML元素,它没有任何子元素或属性,如:<sex>男</sex>。简单元素可以附加地定义其缺省值或固定值。XSD定义简单元素的格式是: <xs:element name="xxx" type="ttt"[default="defval"] [fixed="fixedval"]>。其中ttt使用XSD标准定义的基本类型,即:xs:string、xs:decimal、xs:integer、xs:boolean、xs:date、 xs:time等。 例如:<xs:element name=”sex” type=”xs:string” default=”男”>。 使用上述方式定义的简单元素只能限定元素的数据类型、缺省值、固定值。如果希望限定该简单元素的取值范围等约束,则应使用简单类型定义,并在简单类型中嵌套值约束子元素。如:
<xs:element name="sex"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="男"/> <xs:enumeration value="女"/> </xs:restriction> </xs:simpleType> </xs:element> 复杂元素描述 复杂元素指包含属性或子元素的XML元素,如:<student name=”Li” sex=”男”>,主要包括下列四类: l 空元素:只包含属性的元素。如:<student name=”li” />; l 只包含属性与子元素的元素。如:
<name type=”realname”> <firstname>Jack</firstname> <lastname>Tom</lastname> </name> l 只包含属性与text的元素。如: <name type=”firstname”>Jack</name> l 只包含属性、text和子元素的元素。如: <name type=”realname”> Your name is: <firstname>xxx</firstname> <lastname>xxx</lastname> </name> 复杂元素是一种复杂类型,可以使用下面两种描述方式,一是复合结构,二是分离结构。复合结构,则直接将复杂类型定义为复杂元素的子元素;分离结构则是将复杂类型定义在外部,由复杂元素引用。 l 复合结构 <xs:element name="xxx"> <xs:complexType> ... </xs:complexType> </xs:element> l分离结构 <xs:element name="xxx" type=”yyy” /> <xs:complexTypename=”yyy”> ... </xs:complexType> 这两种描述结构也适合于属性、简单元素的描述。如果XSD元素中存在大量可复用的自定义数据类型时,建议使用分离式的定义结构。 Eg: a: 空元素描述 空元素通常使用<xs:complexType>描述: <xs:element name="product"> b:只包含text的元素描述 <xs:element name="somename" type=”xs:string”/> c:
5.数据类型 XSD的数据类型包括基本数据类型、简单数据类型、复杂数据类型三类。基本数据类型指W3C标准定义的数据类型,主要包括xs:integer、xs:string、xs:date、xs:boolean等。简单数据类型是基本数据类型的扩展,对取值进行约束;复杂数据类型则是一个复杂的数据结构,通常包含了属性或子元素定义。 (1)简单类型 simpleType 简单类型扩展基本数据类型,并对值施加一定的约束。如:
<xs:simpleType name="XSDSimpleType"> <xs:restriction base="dateTime"> <xs:enumeration value="value1" /> <xs:enumeration value="value2" /> <xs:enumeration value="value3" /> </xs:restriction> </xs:simpleType> 数据类型的限定(约束)
(2)复杂类型 complexType 复杂类型通常是复杂元素的数据类型或复杂元素的子元素,描述复杂元素的子元素、属性以及子元素与属性的类型。参看后续各小节的描述。 6.属性 属性本身总是定义为简单类型的。属性可以指定缺省值、固定值、强制项、约束等属性。属性定义格式是:<xs:attribute name="xxx" type="ttt"[default="ddd"] [fixed="fff"] [use="required"]>。 如:<xs:attribute name="orderid" type="xs:string"use="required"/> 或 <xs:attribute name="orderid" > <xs:simpleTypename="orderIdType"> <xs: restriction base= "string" >";
7.复杂类型指令(指示器) 复杂类型指令控制子元素如何在复杂元素中使用,包括三类指令:(Order)顺序、(Occurrence)次数、(Group)分组。 (1)顺序 顺序指令控制子元素是否按顺序出现,包含三种类型: l <xs:all> 指示这些子元素最多出现一次,且顺序无关(minOccurs=0,maxOccurs=1)。n?? /???`F?n lang=EN-US style='font-size:10.0pt;font-family:"Courier New";mso-fareast-font-family:"Times New Roman";color:teal'><xs:attribute name="orderid" ><xs:simpleTypename="orderIdType"> <xs: restriction base= "string" ><xs:complexType name="fullpersoninfo">
<xs:all>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:all>
</xs:complexType>
? <xs:sequencs>
指示这些子元素必须按顺序出现。
<xs:complexType name="fullpersoninfo">
<xs:sequencs>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
? <xs:choice>
指示这些子元素只能出现其中一个。
<xs:complexType name="fullpersoninfo">
<xs:choice>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:choice>
</xs:complexType>
(2)次数 次数指令作为元素的属性,控制元素可以出现的次数,包含两个指令:minOccurs、maxOccurs。如: <element name="B2C"type="string"minOccurs="3"maxOccurs="4"></element> (3)组 组指令指示一个元素或属性集合。 元素组使用<xs:group name="xxx">嵌套一个all、choice、sequence指令;定义后,使用<xs:group ref="name">引用元素组。 属性组使用<xs:attributeGroup name="xxx">嵌套多个<attribute>属性定义。定义后,使用<xs:attributeGroup ref="name">引用属性组。 复杂类型还可以使用一些特殊的标记扩展文档。 l <xs:any minOccurs ="0" > 指示可以在此位置包含任何其他元素;(这些元素也必须在Schema文档中进行定义) l <xs:anyAttribute>指示可以在此位置包含任何其他的属性。(这些属性也必须在Schema文档中进行定义) 在把group定义完毕以后,就可以在另一个定义中引用它了。(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |