第2章 XML节点访问

2.1 设计需求

给定如下XML文档:

<?xml version="1.0" encoding="utf-8"?>
<books>
    <head>some books</head>
    <book category="web_front-end" test="1">
        <ISBN>8475484848</ISBN>
        <title>XML技术</title>
        <price>80</price>
    </book>
    <book>
        <ISBN>35235348</ISBN>
        <title>Python programming</title>
        <price>65</price>
    </book>
    <book>
        <ISBN>67676348</ISBN>
        <title>Java development</title>
        <price>76</price>
    </book>
    <book>
        <ISBN>27974348</ISBN>
        <title>NodeJS development</title>
        <price>90</price>
    </book>
</books>

提出如下设计需求:

使用XML DOM技术实现以下功能:

  1. 访问根结点的属性(outerHTML、innerHTML、nodeName、nodeValue、nodeType、textContent)。
  2. 访问标记名为"book"的第1个元素节点的属性(nodeName、nodeValue、nodeType、textContent)。
  3. 访问根节点内部第1个文本节点的属性(nodeName、nodeValue、nodeType、textContent)。
  4. 访问根节点内部第1个属性节点的属性(nodeName、nodeValue、nodeType、textContent)。
  5. 用户从下拉列表中选择表达式,表达列表中包含实现以上访问的指令。
  6. 设计效果见:106.75.145.231/XML_FC/2/main.html

2.2 设计分析

2.2.1 功能分析

测试用户期望功能如下:

  1. 访问根结点的指定属性。
  2. 访问标记名为"book"的第1个元素节点的指定属性。
  3. 访问根节点内部第1个文本节点的指定属性。
  4. 访问根节点内部第1个属性节点的指定属性。
  5. 选择下拉列表中指令选项实现以上访问。

测试用户用例建模如图2.1所示。

图2.1 测试用户用例建模

2.2.2 数据流分析

数据流核心环节描述如下:

  1. 文件处理框架读取XML源文件并生生可视标记文本数据。
  2. 浏览器解析器解析节点访问指令并输出格式化结果。

数据流核心环节建模如图2.2所示。

图2.2 数据流核心环节

2.2.3 文件包设计分析

基于分层架构视角的文件包及文件设计如表1.1所述。

序号 包设计 文件设计
1 设计表示层包(包名:UI),相当表示层文件容器。 (1) 设计界面主页文件main.js。
(2) 主页引入jquery框架(jquery.js),辅助表示层处理,也可读取测试文件。
2 设计数据层包(包名:data),相当数据层文件容器。 (1) 设计XML数据测试文件books.xml。

文件包建模如图2.3所示。

图2.3 文件包建模

2.3 文件架构

文件架构如图2.4所示。

图2.4 文件架构

文件功能说明见表2.2所述。

序号 文件名 作用
1 books.xml 用于测试的XML基础数据
2 jquery-1.11.1.js 加载JQuery函数库,辅助数据可视处理及读取测试基础数据。
3 main.html 实现人机交互的用户界面主页
4 UI 界面处理逻辑文件所在文件夹
5 data 数据文件所在文件夹

说明:实际应用中,考虑到$.get()不能跳出当前文件夹读取文件,主页文件暂时放在UI外围。

2.4 代码实现

2.4.1 主页实现

主页文件main.html代码如下:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <h2>访问XMLDom测试</h2>
    <hr />
    <span style="font-weight:600">XML文档文本数据:</span>
    <br />
    <textarea id="XMLtext" style="width:500px;height:300px;color:blue"></textarea>
    <hr />
    <span style="font-weight:600">访问节点指令选项</span>
    <br />
    <select disabled="disabled" id="instru_sele" onchange="access_node()">
        <option>清空结果</option>
        <option>xmldom.documentElement.outerHTML</option>
        <option>xmldom.documentElement.innerHTML</option>
        <option>xmldom.documentElement.nodeName</option>
        <option>xmldom.documentElement.nodeValue</option>
        <option>xmldom.documentElement.nodeType</option>
        <option>xmldom.documentElement.textContent</option>
        <option>xmldom.getElementsByTagName("head")[0].childNodes[0].nodeName</option>
        <option>xmldom.getElementsByTagName("head")[0].childNodes[0].nodeValue</option>
        <option>xmldom.getElementsByTagName("head")[0].childNodes[0].nodeType</option>
        <option>xmldom.getElementsByTagName("head")[0].childNodes[0].textContent</option>
        <option>xmldom.getElementsByTagName("book")[0].nodeName</option>
        <option>xmldom.getElementsByTagName("book")[0].nodeValue</option>
        <option>xmldom.getElementsByTagName("book")[0].nodeType</option>
        <option>xmldom.getElementsByTagName("book")[0].textContent</option>
        <option>xmldom.getElementsByTagName("book")[0].getAttributeNode("category").nodeName</option>
        <option>xmldom.getElementsByTagName("book")[0].getAttributeNode("category").nodeValue</option>
        <option>xmldom.getElementsByTagName("book")[0].getAttributeNode("category").nodeType</option>
        <option>xmldom.getElementsByTagName("book")[0].getAttributeNode("category").textContent</option>
    </select>
    <hr />
    <span style="font-weight:600">访问结果:</span><br />
    <textarea id="result" style="width:500px;height:100px;color:red"></textarea>
</body>
</html>

<script type="text/javascript" src="./UI/jquery-1.11.1.js"></script>

<script type="text/javascript">
//初始化
var xmldom;

$.get("./data/books.xml", function (data) {
    xmldom = $.parseXML(data);
    $("#XMLtext").text(data);
    $("#instru_sele").attr("disabled",false);
}, "text");

//访问节点
function access_node() {
    var instruc = $("#instru_sele option:selected").text();
    if (instruc =="清空结果") { $("#result").text(""); }
    else { $("#result").text(eval(instruc)); }
}
</script>

2.4.2 实现效果

访问根节点outerHTML属性如图2.5所示。

访问第1个文本节点的nodeName属性如图2.6所示。

访问第1个属性节点的nodeValue属性如图2.7所示。

图2.5 访问根节点示例 图2.6 访问文本节点示例 图2.7 访问属性节点示例

2.5 问题思考

问题提出:基于本章案例演示,XML文档存储结构的主要特点是什么?

问题思考:

  1. XML文档可通过一定的加载方式形成树型存储结构。
  2. XML文档节点访问类似HTML文档。
  3. XML文档节点可分为:元素节点、文本节点、属性节点。
  4. XML文档节点均具有可访问属性:nodeName、nodeValue、nodeType、textContent。
  5. 元素节点的nodeValue属性值为"null"。
  6. 属性节点、文本节点的nodeValue属性值与textContent属性值一致。
  7. 元素节点的nodeType属性值为"1"、属性节点的nodeType属性值为"2"、文本节点的nodeType属性值为"3"。

2.6 仿真实训

给定如下XML文档:

<?xml version="1.0" encoding="utf-8"?>
<students>
    <head>some students</head>
    <student category="new_student">
        <s_id>8475484848</s_id>
        <s_name>Max</s_name>
        <age>18</age>
    </student>
    <student>
        <s_id>35235348</s_id>
        <s_name>Jack</s_name>
        <age>20</age>
    </student>
    <student>
        <s_id>67676348</s_id>
        <s_name>Json</s_name>
        <age>21</age>
    </student>
    <student>
        <s_id>27974348</s_id>
        <s_name>Rose</s_name>
        <age>19</age>
    </student>
</students>

请根据以下设计需求实现相关应用。

  1. 访问根结点的属性(outerHTML、innerHTML、nodeName、nodeValue、nodeType、textContent)。
  2. 访问标记名为"student"的第1个元素节点的属性(nodeName、nodeValue、nodeType、textContent)。
  3. 访问根节点内部第1个文本节点的属性(nodeName、nodeValue、nodeType、textContent)。
  4. 访问根节点内部第1个属性节点的属性(nodeName、nodeValue、nodeType、textContent)。
  5. 仿真本章案例功能实现以上设计。