Paste_Image.png

XML即可扩展标记语言(eXtensible Markup Language)。标记是指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等。如何定义这些标记,既可以选择国际通用的标记语言,比如HTML,也可以使用象XML这样由相关人士自由决定的标记语言,这就是语言的可扩展性。XML是从SGML中简化修改出来的。它主要用到的有XML、XSL和XPath等。

什么是 XML?

  • XML 指可扩展标记语言(EXtensible Markup Language)。
  • XML 是一种很像HTML的标记语言。
  • XML 的设计宗旨是传输数据,而不是显示数据。
  • XML 标签没有被预定义。您需要自行定义标签。
  • XML 被设计为具有自我描述性。
  • XML 是 W3C 的推荐标准。

XML 用途

  1. XML 把数据从 HTML 分离
  2. XML 简化数据共享
  3. XML 简化数据传输
  4. XML 简化平台变更
  5. XML 使您的数据更有用
  6. XML 用于创建新的互联网语言

XML 语法规则

XML 的语法规则很简单,且很有逻辑。这些规则很容易学习,也很容易使用

XML 文档必须有根元素

XML 必须包含根元素,它是所有其他元素的父元素,比如以下实例中 root 就是根元素:

1
2
3
4
5
<root>
<child>
<subchild>.....</subchild>
</child>
</root>

以下实例中 note 是根元素:

1
2
3
4
5
6
7
<?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 声明文件的可选部分,如果存在需要放在文档的第一行,如下所示:

1
<?xml version="1.0" encoding="utf-8"?>

以上实例包含 XML 版本(UTF-8 也是 HTML5, CSS, JavaScript, PHP, 和 SQL 的默认编码)。

所有的 XML 元素都必须有一个关闭标签

在 HTML 中,某些元素不必有一个关闭标签:

1
2
<p>This is a paragraph.
<br>

在 XML 中,省略关闭标签是非法的。所有元素都必须有关闭标签:

1
2
<p>This is a paragraph.</p>
<br/>

注释: 从上面的实例中,您也许已经注意到 XML 声明没有关闭标签。这不是错误。声明不是 XML 文档本身的一部分,它没有关闭标签。

XML 标签对大小写敏感

XML 标签对大小写敏感。标签 与标签 是不同的。
必须使用相同的大小写来编写打开标签和关闭标签:

1
2
<Message>这是错误的</message>
<message>这是正确的</message>

注释: 打开标签和关闭标签通常被称为开始标签和结束标签。不论您喜欢哪种术语,它们的概念都是相同的。

XML 必须正确嵌套

在 HTML 中,常会看到没有正确嵌套的元素:

1
<b><i>This text is bold and italic</b></i>

在 XML 中,所有元素都必须彼此正确地嵌套:

1
<b><i>This text is bold and italic</i></b>

在上面的实例中,正确嵌套的意思是:由于 <i> 元素是在 <b> 元素内打开的,那么它必须在 <b> 元素内关闭

XML 属性值必须加引号

与 HTML 类似,XML 元素也可拥有属性(名称/值的对)。
在 XML 中,XML 的属性值必须加引号。
请研究下面的两个 XML 文档。 第一个是错误的,第二个是正确的:

1
2
3
4
5
6
7
8
<note date=12/11/2007>
<to>Tove</to>
<from>Jani</from>
</note>
<note date="12/11/2007">
<to>Tove</to>
<from>Jani</from>
</note>

在第一个文档中的错误是,note 元素中的 date 属性没有加引号。

实体引用

在 XML 中,一些字符拥有特殊的意义。
如果您把字符 “<” 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。
这样会产生 XML 错误:

1
<message>if salary < 1000 then</message>

为了避免这个错误,请用实体引用来代替 “<” 字符:

1
<message>if salary &lt; 1000 then</message>

在 XML 中,有 5 个预定义的实体引用:

< < less than
> > greater than
——- —-
& & ampersand
——- —-
' apostrophe
——- —-
" quotation mark
注释: 在 XML 中,只有字符 “<” 和 “&” 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。

XML 中的注释

1
<!-- 注释 -->

在 XML 中,空格会被保留

HTML 会把多个连续的空格字符裁减(合并)为一个:

HTML: Hello Tove
Output: Hello Tove
在 XML 中,文档中的空格不会被删减

XML 以 LF 存储换行

在 Windows 应用程序中,换行通常以一对字符来存储:回车符(CR)和换行符(LF)。

在 Unix 和 Mac OSX 中,使用 LF 来存储新行。

在旧的 Mac 系统中,使用 CR 来存储新行。

XML 以 LF 存储换行。

XML语法

XML文档声明

1
<?xml version="1.0" encoding="UTF-8" ?>
  • 文档声明必须为<?xml 开头,以?>结束
  • 文档声明必须从文档的0行0列位置开始,也就是说必须放在顶部位置
  • 文档声明只有三个属性:
    • version:指定xml文档版本。必须属性,因为我们不会选择1.1,只会选择1.0
    • encoding:指定当前文档的编码。可选属性。默认值是utf-8

元素

  • 元素是XML文档中最重要的组成部分

  • 普通元素的结构开始标签、元素体、结束标签组成。例如:

    1
    <hello>大家好</hello>
  • 元素体:元素体可以是元素,也可以是文本,例如:

    1
    <hello><world>hello world!</world></hello>
  • 空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭合,例如:
    <c/>

  • 元素命名

    1. 区分大小写
    2. 不能使用空格,不能使用冒号
    3. 不建议以xml、XML、Xml开头
  • 格式化良好的xml文档,必须只有一个根元素

属性

1
<web-app version="2.5">
  1. 属性是元素的一部分,他必须出现在元素的开始标签中
  2. 属性的定义格式:属性名=属性值,其中,属性值必须使用单引/双引
  3. 一个元素可以有0~N个属性,但一个元素中不能出现同名属性
  4. 属性名不能使用空格、冒号等特殊字符,且必须以字母开头

PCDATA

PCDATA 的意思是被解析的字符数据(parsed character data)。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 “&amp”;、”&lt”; 以及 “&gt”; 实体来分别替换它们。

CDATA

术语 CDATA 指的是不应由 XML 解析器进行解析的文本数据(Unparsed Character Data)。
在 XML 元素中,”<” 和 “&” 是非法的。
“<” 会产生错误,因为解析器会把该字符解释为新元素的开始。
“&” 也会产生错误,因为解析器会把该字符解释为字符实体的开始。
某些文本,比如 JavaScript 代码,包含大量 “<” 或 “&” 字符。为了避免错误,可以将脚本代码定义为 CDATA。
CDATA 部分中的所有内容都会被解析器忽略。
CDATA 部分由 ““ 结束:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
<![CDATA[
function matchwo(a,b)
{
if (a < b && a < 0) then
{
return 1;
}
else
{
return 0;
}
}
]]>
</script>

在上面的例子中,解析器会忽略 CDATA 部分中的所有内容。

DTD

DTD

文档类型定义(Document Type Definition)是一套为了进行程序间的数据交换而建立的关于标记符的语法规则。它是标准通用标记语言和可扩展标记语言1.0版规格的一部分,文档可根据某种DTD语法规则验证格式是否符合此规则。文档类型定义也可用做保证标准通用标记语言、可扩展标记语言文档格式的合法性,可通过比较文档和文档类型定义文件来检查文档是否符合规范,元素和标签使用是否正确。文件实例提供应用程序一个数据交换的格式。使用各类文档类型定义是为了让标准通用标记语言、可扩展标记语言文件能符合规定的数据交换标准,因为这样,不同的公司只需定义好标准文档类型定义,就都能依文档类型定义建立文档实例,并且进行验证,如此就可以轻易交换数据,防止了实例数据定义不同等原因造成的数据交换障碍,满足了网络共享和数据交互。文档类型定义文件是一个美国信息交换标准代码文本文件。

为什么使用DTD文档

  • 通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
  • 通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
    而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
  • 您还可以使用 DTD 来验证您自身的数据。

内部的 DOCTYPE 声明

假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:

1
<!DOCTYPE root-element [element-declarations]>

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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>

以上 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” 类型

外部文档声明

假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:

1
<!DOCTYPE root-element SYSTEM "filename">

这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD: (点击打开该文件,并选择”查看源代码”命令。)

1
2
3
4
5
6
7
8
<?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” 文件:

1
2
3
4
5
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

DTD元素

在一个 DTD 中,元素通过元素声明来进行声明。

声明一个元素

在 DTD 中,XML 元素通过元素声明来进行声明。元素声明使用下面的语法:

1
<!ELEMENT element-name category>

1
<!ELEMENT element-name (element-content)>

空元素

空元素通过类别关键词EMPTY进行声明:

1
<!ELEMENT element-name EMPTY>

实例:

1
<!ELEMENT br EMPTY>

XML example:

1
<br />

只有 PCDATA 的元素

只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:

1
<!ELEMENT element-name (#PCDATA)>

实例:

1
<!ELEMENT from (#PCDATA)>

带有任何内容的元素

通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:

1
<!ELEMENT element-name ANY>

实例:

1
<!ELEMENT note ANY>

带有子元素(序列)的元素

带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:

1
<!ELEMENT element-name (child1)>

1
<!ELEMENT element-name (child1,child2,...)>

实例:

1
<!ELEMENT note (to,from,heading,body)>

当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。”note” 元素的完整声明是:

1
2
3
4
5
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

声明只出现一次的元素

1
<!ELEMENT element-name (child-name)>

实例:

1
<!ELEMENT note (message)>

上面的例子声明了:message 子元素必须出现一次,并且必须只在 “note” 元素中出现一次。

声明最少出现一次的元素(+)

1
<!ELEMENT element-name (child-name+)>

实例:

1
<!ELEMENT note (message+)>

上面的例子中的加号(+)声明了:message 子元素必须在 “note” 元素内出现至少一次。

声明出现零次或多次的元素(*)

1
<!ELEMENT element-name (child-name*)>

实例:

1
<!ELEMENT note (message*)>

上面的例子中的星号(*)声明了:子元素 message 可在 “note” 元素内出现零次或多次。

声明出现零次或一次的元素(?)

1
<!ELEMENT element-name (child-name?)>

实例:

1
<!ELEMENT note (message?)>

上面的例子中的问号(?)声明了:子元素 message 可在 “note” 元素内出现零次或一次。

声明”非…/既…”类型的内容

实例:

1
<!ELEMENT note (to,from,header,(message|body))>

上面的例子声明了:”note” 元素必须包含 “to” 元素、”from” 元素、”header” 元素,以及非 “message” 元素既 “body” 元素。

声明混合型的内容

实例:

1
<!ELEMENT note (#PCDATA|to|from|header|message)*>

上面的例子声明了:”note” 元素可包含出现零次或多次的 PCDATA、”to”、”from”、”header” 或者 “message”。

DTD - 属性

在 DTD 中,属性通过 ATTLIST 声明来进行声明。

属性声明使用下列语法:

1
<!ATTLIST element-name attribute-name attribute-type attribute-value>

DTD 实例:

1
<!ATTLIST payment type CDATA "check">

XML 实例:

1
<payment type="check" />

以下是 属性类型的选项:

类型 描述
CDATA 值为字符数据 (character data)
(en1|en2|..) 此值是枚举列表中的一个值
ID 值为唯一的 id
IDREF 值为另外一个元素的 id
IDREFS 值为其他 id 的列表
NMTOKEN 值为合法的 XML 名称
NMTOKENS 值为合法的 XML 名称的列表
ENTITY 值是一个实体
ENTITIES 值是一个实体列表
NOTATION 此值是符号的名称
xml: 值是一个预定义的 XML 值

默认属性值可使用下列值 :

解释
属性的默认值
#REQUIRED 属性值是必需的
#IMPLIED 属性不是必需的
#FIXED value 属性值是固定的

XML解析

XML是一种通用的数据交换格式,它的平台无关性、语言无关性、系统无关性、给数据集成与交互带来了极大的方便。XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已。

XML的解析方式分为四种:1、DOM解析;2、SAX解析;3、JDOM解析;4、DOM4J解析。其中前两种属于基础方法,是官方提供的平台无关的解析方式;后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于java平台。

以下是要解析的XML文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book id="1">
<name>冰与火之歌</name>
<author>乔治马丁</author>
<year>2014</year>
<price>89</price>
</book>
<book id="2">
<name>安徒生童话</name>
<year>2004</year>
<price>77</price>
<language>English</language>
</book>
</bookstore>

一、DOM解析

  DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。

  DOM接口提供了一种通过分层对象模型来访问XML文档信息的方式,这些分层对象模型依据XML的文档结构形成了一棵节点树。无论XML文档中所描述的是什么类型的信息,即便是制表数据、项目列表或一个文档,利用DOM所生成的模型都是节点树的形式。也就是说,DOM强制使用树模型来访问XML文档中的信息。由于XML本质上就是一种分层结构,所以这种描述方法是相当有效的。

  DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的使用价值的。

    优点:

      1、形成了树结构,有助于更好的理解、掌握,且代码容易编写。

      2、解析过程中,树结构保存在内存中,方便修改。

    缺点:

      1、由于文件是一次性读取,所以对内存的耗费比较大。

      2、如果XML文件比较大,容易影响解析性能且可能会造成内存溢出。

以下是解析代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.hyf;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* DOM解析XML文件
* @author Administrator
*
*/
public class DOMParseXmlTest {
public static void main(String[] args) {
//创建一个DocumentBuilderFactory的对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//创建一个DocumentBuilder的对象
try {
DocumentBuilder db = dbf.newDocumentBuilder();
//通过DocumentBuilder对象的parser方法加载books.xml文件到当前项目下
System.out.println("开始加载books.xml文件......");
Document document = db.parse("books.xml");
//获取所有book节点的集合
NodeList bookList = document.getElementsByTagName("book");
//通过nodelist的getLength()方法可以获取bookList的长度
System.out.println("一共有"+bookList.getLength()+"本书");
//遍历每一个book节点
for (int i = 0; i < bookList.getLength(); i++) {
// 第几本书
int NO = i+1;
System.out.println("=================下面开始遍历第" + NO + "本书的内容=================");
//通过 item(i)方法 获取一个book节点,nodelist的索引值从0开始
Node node = bookList.item(i);
NamedNodeMap attributes = node.getAttributes();
System.out.println("第"+NO+"本书有"+attributes.getLength()+"个属性");
// 遍历属性
for (int j = 0; j < attributes.getLength(); j++) {
System.out.println("属性名字:"+attributes.item(j).getNodeName()+",属性值:"+attributes.item(j).getNodeValue());
}
//遍历子元素
NodeList childNodes = node.getChildNodes();
System.out.println("第"+NO+"本书有"+childNodes.getLength()+"个子节点");

for (int k = 0; k < childNodes.getLength(); k++) {
//区分出text类型的node以及element类型的node
if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {
//获取了element类型节点的节点名
System.out.print("第" + (k + 1) + "个节点的节点名:"
+ childNodes.item(k).getNodeName());
//获取了element类型节点的节点值
System.out.println("--节点值是:" + childNodes.item(k).getFirstChild().getNodeValue());
//System.out.println("--节点值是:" + childNodes.item(k).getTextContent());
}
}
}

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
开始加载books.xml文件......
一共有2本书
=================下面开始遍历第1本书的内容=================
第1本书有1个属性
属性名字:id,属性值:1
第1本书有9个子节点
第2个节点的节点名:name--节点值是:冰与火之歌
第4个节点的节点名:author--节点值是:乔治马丁
第6个节点的节点名:year--节点值是:2014
第8个节点的节点名:price--节点值是:89
=================下面开始遍历第2本书的内容=================
第2本书有1个属性
属性名字:id,属性值:2
第2本书有9个子节点
第2个节点的节点名:name--节点值是:安徒生童话
第4个节点的节点名:year--节点值是:2004
第6个节点的节点名:price--节点值是:77
第8个节点的节点名:language--节点值是:English

二、SAX解析

  SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。

    优点:

      1、采用事件驱动模式,对内存耗费比较小。

      2、适用于只处理XML文件中的数据时。

    缺点:

      1、编码比较麻烦。

      2、很难同时访问XML文件中的多处不同数据。

三、pull解析(android 推荐)

Pull内置于Android系统中。也是官方解析布局文件所使用的方式。Pull与SAX有点类似,都提供了类似的事件,如开始元素和结束元素。不同的是,SAX的事件驱动是回调相应方法,需要提供回调的方法,而后在SAX内部自动调用相应的方法。而 Pull解析器并没有强制要求提供触发的方法。因为他触发的事件不是一个方法,而是一个数字。它使用方便,效率高。

常见的解析开发包

  • JAXP:sun公司提供支持DOM和SAX开发包
  • JDOM:dom4j兄弟
  • jsoup:一种处理html特定解析开发包
  • dom4j:比较常见的解析开发包,hibernate底层采用。

DOM4J解析XML文档

jar包

下载地址:链接:http://pan.baidu.com/s/1c2LFBRa 密码:e7uc

dom4j必须使用核心类SaxReader加载xml文档获得document,通过document对象获得文档的根元素,然后就可以操作了。

解析代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.hyf;

import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.tree.DefaultAttribute;

public class DOM4JParseXMLTest {

public static void main(String[] args) {
// TODO Auto-generated method stub
// 1 获取解析器
SAXReader saxReader = new SAXReader();
// 2 获得document文档对象
try {
Document document = saxReader.read("books.xml");
// 3 获取根元素
Element rootElement = document.getRootElement();
System.out.println("获取根元素成功----------"+rootElement.getName());
// 4 根元素有几个子节点
List<Element> books = rootElement.elements();
System.out.println(rootElement.getName()+"中共有"+books.size()+"本书籍");
for (int i = 0; i < books.size(); i++) {
System.out.println("【第"+(i+1)+"本书】");
Element book = books.get(i);
List<DefaultAttribute> attributes = book.attributes();
System.out.println("共有"+attributes.size()+"条属性");
for (DefaultAttribute defaultAttribute : attributes) {
System.out.println("属性名:"+defaultAttribute.getName()+",属性值:"+defaultAttribute.getValue());
}
List<Element> bookDetails = book.elements();
for (Element element : bookDetails) {
System.out.println(element.getName()+">>>>"+element.getStringValue());
}

}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

解析结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
获取根元素成功----------bookstore
bookstore中共有2本书籍
【第1本书】
共有1条属性
属性名:id,属性值:1
name>>>>冰与火之歌
author>>>>乔治马丁
year>>>>2014
price>>>>89
【第2本书】
共有1条属性
属性名:id,属性值:2
name>>>>安徒生童话
year>>>>2004
price>>>>77
language>>>>English


后台     

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!