XML笔记
XML 相关技术列表:
- XML (可扩展标记语言 e**X**tensible **M**arkup **L**anguage)-传输和存储数据。
- XHTML (可扩展 HTML)-更严格更纯净的基于 XML 的 HTML 版本。
- XML DOM (XML 文档对象模型)-访问和操作 XML 的标准文档模型。
- XSL (可扩展样式表语言) XSL 包含三个部分:
- XQuery (XML 查询语言)-基于 XML 的用于查询 XML 数据的语言。
- DTD (文档类型定义)-用于定义 XML 文档中的合法元素的标准。
- XSD (XML 架构)-基于 XML 的 DTD 替代物。
- XLink (XML 链接语言)-在 XML 文档中创建超级链接的语言。
- XPointer (XML 指针语言)-允许 XLink 超级链接指向 XML 文档中更多具体的部分。
- SOAP (简单对象访问协议)-允许应用程序在 HTTP 之上交换信息的基于 XML 的协议。
- WSDL (Web 服务描述语言)-用于描述网络服务的基于 XML 的语言。
- RDF (资源描述框架)-用于描述网络资源的基于 XML 的语言。
- RSS (真正简易聚合)-聚合新闻以及类新闻站点内容的格式。
- SVG (可伸缩矢量图形)-定义 XML 格式的图形。
XML
基本语法
XML语法规则:
- XML 文档必须有一个根元素
- XML元素都必须有一个关闭标签。声明不是 XML 文档本身的一部分,它没有关闭标签。声明如果存在需要放在文档的第一行。
- XML 标签对大小写敏感
- XML 元素必须被正确的嵌套
- XML 属性值必须加引号,不过单引号和双引号均可使用。如果属性值本身包含双引号,您可以使用单引号。或者您可以使用字符实体。属性可提供有关元素的额外信息。属性总是被置于某元素的开始标签中。属性总是以名称/值的形式成对出现的。元数据(有关数据的数据)应当存储为属性,而数据本身应当存储为元素。
XML 文档使用简单的具有自我描述性的语法:
<?xml version="1.0" encoding="UTF-8"?>
<!--第一行是 XML 声明。它定义 XML 的版本(1.0)和所使用的编码(UTF-8 : 万国码, 可显示各种语言)。-->
<!--XML 文档必须包含根元素。该元素是所有其他元素的父元素。-->
<root>
<!--XML 文档中的元素形成了一棵文档树。这棵树从根部开始,并扩展到树的最底端。-->
<child>
<!--父、子以及同胞等术语用于描述元素之间的关系。父元素拥有子元素。相同层级上的子元素成为同胞(兄弟或姐妹)。-->
<subchild>.....</subchild>
<!--所有的元素都可以有文本内容和属性。-->
</child>
</root>
示例:
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
XML注意事项:
- 在 XML 中,文档中的空格不会被删减。
- XML 以 LF(换行符) 存储换行。
- 在 XML 中,只有字符 “<” 和 “&” 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。
在 XML 中,有 5 个预定义的实体引用:
实体引用 | 实体符号 | 实体含义 |
---|---|---|
< | < | less than |
> | > | greater than |
& | & | ampersand |
' | ‘ | apostrophe |
" | “ | quotation mark |
XML 元素必须遵循以下命名规则:
- 名称可以包含字母、数字以及其他的字符
- 名称不能以数字或者标点符号开始
- 名称不能以字母 xml(或者 XML、Xml 等等)开始
- 名称不能包含空格
XML 元素最佳命名习惯
- 名称具有描述性,应简短和简单。
- 名称可以使用下划线,避免 “-” 、”.” 、”:” 字符。冒号会被转换为命名空间来使用。
命名空间
在 XML 中,当两个不同的文档使用相同的元素名时,就会发生命名冲突。命名冲突可以通过使用名称前缀从而容易地避免。当在 XML 中使用前缀时,一个所谓的用于前缀的命名空间必须被定义。
命名空间是在元素的开始标签的 xmlns 属性中定义的。
命名空间声明的语法如下:
xmlns:前缀="URI"
当命名空间被定义在元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联。
命名空间 URI 不会被解析器用于查找信息。其目的是赋予命名空间一个惟一的名称。不过,很多公司常常会作为指针来使用命名空间指向实际存在的网页,这个网页包含关于命名空间的信息。
为元素定义默认的命名空间可以让我们省去在所有的子元素中使用前缀的工作。它的语法如下:
xmlns="namespaceURI"
XML 文档构建模块
所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成:
- 元素
- 属性
- 实体
- PCDATA
- CDATA
PCDATA(parsed character data) 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开。不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。
CDATA(character data) 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
DTD
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。它使用一系列合法的元素来定义文档的结构。
为什么使用 DTD?
- 通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
- 通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
- 而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
- 您还可以使用 DTD 来验证您自身的数据。
实例(请在 IE5 以及更高的版本打开,并选择查看源代码):
<?xml version="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>
DOCTYPE 声明
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
内部的 DOCTYPE 声明
假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:
<!DOCTYPE root-element [element-declarations]>
外部文档声明
假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
<!DOCTYPE root-element SYSTEM "filename">
元素声明
- 声明一个元素:
<!ELEMENT element-name category>
或<!ELEMENT element-name (element-content)>
- 声明空元素:
<!ELEMENT element-name EMPTY>
- 声明带有任何内容的元素:
<!ELEMENT element-name ANY>
- 声明只有 PCDATA 的元素:
<!ELEMENT element-name (#PCDATA)>
- 声明带有子元素(序列)的元素:
<!ELEMENT element-name (child1,child2,...)>
当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。 - 声明只出现一次的元素:
<!ELEMENT element-name (child-name)>
- 声明最少出现一次的元素:
<!ELEMENT element-name (child-name+)>
- 声明出现零次或多次的元素:
<!ELEMENT element-name (child-name*)>
- 声明出现零次或一次的元素:
<!ELEMENT element-name (child-name?)>
- 声明”非…/既…”类型的内容:
<!ELEMENT note (to,from,header,(message|body))>
上面的例子声明了:”note” 元素必须包含 “to” 元素、”from” 元素、”header” 元素,以及非 “message” 元素既 “body” 元素。 - 声明混合型的内容:
<!ELEMENT note (#PCDATA|to|from|header|message)*>
上面的例子声明了:”note” 元素可包含出现零次或多次的 PCDATA、”to”、”from”、”header” 或者 “message”。
声明属性
在 DTD 中,属性通过 ATTLIST 声明来进行声明。
属性声明使用下列语法:
<!ATTLIST element-name attribute-name attribute-type attribute-value>
DTD 实例:
<!ATTLIST payment type CDATA "check">
XML 实例:
<payment type="check" />
以下是 属性类型attribute-type的选项:
类型 | 描述 |
---|---|
CDATA | 值为字符数据 (character data) |
(en1|en2|..) | 此值是枚举列表中的一个值 |
ID | 值为唯一的 id |
IDREF | 值为另外一个元素的 id |
IDREFS | 值为其他 id 的列表 |
NMTOKEN | 值为合法的 XML 名称 |
NMTOKENS | 值为合法的 XML 名称的列表 |
ENTITY | 值是一个实体 |
ENTITIES | 值是一个实体列表 |
NOTATION | 此值是符号的名称 |
xml: | 值是一个预定义的 XML 值 |
默认属性值attribute-value可使用下列值 :
值 | 解释 |
---|---|
value | 属性的默认值 |
REQUIRED | 属性值是必需的 |
IMPLIED | 属性不是必需的 |
FIXED value | 属性值是固定的 |
声明实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
实体引用是对实体的引用。
实体可在内部或外部进行声明。
一个内部实体声明
<!ENTITY entity-name "entity-value">
DTD 实例:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com">
XML 实例:
<author>&writer;©right;</author>
注意: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。
一个外部实体声明
<!ENTITY entity-name SYSTEM "URI/URL">
DTD 实例:
<!ENTITY writer SYSTEM "http://www.runoob.com/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.runoob.com/entities.dtd">
XPath
在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。
下列示例使用这个 XML 文档:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
XPath 语法
选取节点
XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。下面列出了最有用的路径表达式:
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
路径表达式 | 结果 |
---|---|
bookstore | 选取 bookstore 元素的所有子节点。 |
/bookstore | 选取根元素 bookstore。 注释:假如路径起始于正斜杠(>注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
//book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang | 选取名为 lang 的所有属性。 |
谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang=’eng’] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
选取未知节点
XPath 通配符可用来选取未知的 XML 元素。
通配符 | 描述 |
---|---|
* | 匹配任何元素节点。 |
@* | 匹配任何属性节点。 |
node() | 匹配任何类型的节点。 |
text() | 选取节点中的文本。 |
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
/bookstore/* | 选取 bookstore 元素的所有子元素。 |
//* | 选取文档中的所有元素。 |
//title[@*] | 选取所有带有属性的 title 元素。 |
/bookstore/book/price/text() | 选取 price 节点中的所有文本 |
选取若干路径
通过在路径表达式中使用”|”运算符,您可以选取若干个路径。
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
//book/title | //book/price | 选取 book 元素的所有 title 和 price 元素。 |
//title | //price | 选取文档中的所有 title 和 price 元素。 |
/bookstore/book/title | //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
XPath 轴(Axes)
轴可定义相对于当前节点的节点集。
轴名称 | 结果 |
---|---|
ancestor | 选取当前节点的所有先辈(父、祖父等)。 |
ancestor-or-self | 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。 |
attribute | 选取当前节点的所有属性。 |
child | 选取当前节点的所有子元素。 |
descendant | 选取当前节点的所有后代元素(子、孙等)。 |
descendant-or-self | 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 |
following | 选取文档中当前节点的结束标签之后的所有节点。 |
following-sibling | 选取当前节点之后的所有兄弟节点 |
namespace | 选取当前节点的所有命名空间节点。 |
parent | 选取当前节点的父节点。 |
preceding | 选取文档中当前节点的开始标签之前的所有节点。 |
preceding-sibling | 选取当前节点之前的所有同级节点。 |
self | 选取当前节点。 |
XPath 表达式
XPath 表达式可返回节点集、字符串、逻辑值以及数字。
下面列出了可用在 XPath 表达式中的运算符:
运算符 | 描述 | 实例 | 返回值 |
---|---|---|---|
| | 计算两个节点集 | //book | //cd | 返回所有拥有 book 和 cd 元素的节点集 |
+ | 加法 | 6 + 4 | 10 |
- | 减法 | 6 - 4 | 2 |
* | 乘法 | 6 * 4 | 24 |
div | 除法 | 8 div 4 | 2 |
= | 等于 | price=9.80 | 如果 price 是 9.80,则返回 true。 如果 price 是 9.90,则返回 false。 |
!= | 不等于 | price!=9.80 | 如果 price 是 9.90,则返回 true。 如果 price 是 9.80,则返回 false。 |
< | 小于 | price<9.80 | 如果 price 是 9.00,则返回 true。 如果 price 是 9.90,则返回 false。 |
<= | 小于或等于 | price<=9.80 | 如果 price 是 9.00,则返回 true。 如果 price 是 9.90,则返回 false。 |
> | 大于 | price>9.80 | 如果 price 是 9.90,则返回 true。 如果 price 是 9.80,则返回 false。 |
>= | 大于或等于 | price>=9.80 | 如果 price 是 9.90,则返回 true。 如果 price 是 9.70,则返回 false。 |
or | 或 | price=9.80 or price=9.70 | 如果 price 是 9.80,则返回 true。 如果 price 是 9.50,则返回 false。 |
and | 与 | price>9.00 and price<9.90 | 如果 price 是 9.80,则返回 true。 如果 price 是 8.50,则返回 false。 |
mod | 计算除法的余数 | 5 mod 2 | 1 |