《Javascript 高级程序设计(第三版)》笔记0x20 ECMAScript for XML

207 阅读6分钟

目录

E4X 的类型

    XML类型

    XMLList类型

    Namespace类型

    QName类型

一般用法

    访问特性

    其他节点类型

    查询

    构建和操作XML

    解析和序列化

    命名空间


E4X 的类型

    XML类型

    XML 类型是 E4X 中定义的一个重要的新类型,可以用它来表现 XML 结构中任何独立的部分。 XML的实例可以表现元素、特性、注释、处理指令或文本节点。 XML 类型继承自 Object 类型,因此它也继承了所有对象默认的所有属性和方法。

//创建xml
var x = new XML();

var x = new XML("<employee position=\"Software Engineer\"><name>Nicholas " +
		"Zakas</name></employee>");
		
var x = new XML(xmldom);

//使用XML字面量将XML数据直接指定给一个变量。XML字面量就是嵌入到JavaScript代码中的 XML 代码
var employee = 	<employee position="Software Engineer">
			<name>Nicholas C. Zakas</name>
		</employee>;

    XML 类型的 toXMLString()方法会返回 XML 对象及其子节点的 XML 字符串表示。另一方面,该类型的 toString()方法则会基于不同 XML 对象的内容返回不同的字符串。如果内容简单(纯文本),则返回文本;否则, toString()方法与 toXMLString()方法返回的字符串一样。

var data = <name>Nicholas C. Zakas</name>;
alert(data.toString()); //"Nicholas C. Zakas"
alert(data.toXMLString()); //"<name>Nicholas C. Zakas</name>"

    XMLList类型

    XMLList 类型表现 XML 对象的有序集合。 XMLList 的 DOM 对等类型是 NodeList,但与 Node 和NodeList 之间的区别相比, XML 和 XMLList 之间的区别是有意设计得比较小的。

var list = new XMLList();

var list = new XMLList("<item/><item/>");+

var list = <item/> + <item/> ;
//同样的组合操作也可以使用特殊的<>和</>语法来完成,此时不使用加号操作符
var list = <><item/><item/></>;

var employees = <employees>
<employee position="Software Engineer">
<name>Nicholas C. Zakas</name>
</employee>
<employee position="Salesperson">
<name>Jim Smith</name>
</employee>
</employees>;
var firstEmployee = employees.employee[0];
var secondEmployee = employees.employee[1];
//XMLList 对象都有 length()方法,用于返回对象中包含的元素数量
alert(employees.employee.length()); //2

    Namespace类型

    E4X 中使用 Namespace 对象来表现命名空间。通常, Namespace 对象是用来映射命名空间前缀和命名空间 URI 的,不过有时候并不需要前缀。

var ns = new Namespace("http://www.wrox.com/"); //没有前缀的命名空间
var wrox = new Namespace("wrox", "http://www.wrox.com/"); //wrox 命名空间

alert(ns.uri); //"http://www.wrox.com/"
alert(ns.prefix); //undefined
alert(wrox.uri); //"http://www.wrox.com/"
alert(wrox.prefix); //"wrox"

var xml = <wrox:root xmlns:wrox="http://www.wrox.com/">
        <wrox:message>Hello World!</wrox:message>
        </wrox:root>;
var wrox = xml.namespace("wrox");
alert(wrox.uri);
alert(wrox.prefix);

    QName类型

    QName 类型表现的是 XML 对象的限定名,即命名空间与内部名称的组合。向 QName 构造函数中传入名称或 Namespace 对象和名称,可以手工创建新的 QName 对象

var wrox = new Namespace("wrox", "http://www.wrox.com/");
var wroxMessage = new QName(wrox, "message"); //表示"wrox:message"
alert(wroxMessage.uri); //"http://www.wrox.com/"
alert(wroxMessage.localName); //"message

var xml = < wrox:root xmlns:wrox="http://www.wrox.com/">
	wrox:message>Hello World!</wrox:message>
	</wrox:root> ;
var wroxRoot = xml.name();
alert(wroxRoot.uri); //"http://www.wrox.com/"
alert(wroxRoot.localName); //"root"
xml.setName(new QName("newroot"));
xml.setLocalName("newtagname");

一般用法

    在将 XML 对象、元素、特性和文本集合到一个层次化对象之后,就可以使用点号加特性或标签名的方式来访问其中不同的层次和结构。每个子元素都是父元素的一个属性,而属性名与元素的内部名称相同。如果子元素只包含文本,则相应的属性只返回文本。

var employee = <employee position="Software Engineer">
	<name>Nicholas C. Zakas</name>
	</employee>;
alert(employee.name); //"Nicholas C. Zakas"

var employees = <employees>
	<employee position="Software Engineer">
		<name>Nicholas C. Zakas</name>
	</employee>
	<employee position="Salesperson">
		<name>Jim Smith</name>
	</employee>
	</employees>;
alert(employees.employee[0].name); //"Nicholas C. Zakas"
alert(employees.employee[1].name); //"Jim Smith"

var allChildren = employees.*; //返回所有子元素,不管其名称是什么
alert(employees.*[0].name); //"Nicholas C. Zakas"

    访问特性

    访问特性也可以使用点语法,不过其语法稍有扩充。为了区分特性名与子元素的标签名,必须在名称前面加上一个@字符。这是从 XPath 中借鉴的语法; XPath 也是使用@来区分特性和标签的名称。

var employees = <employees>
		<employee position="Software Engineer">
			<name>Nicholas C. Zakas</name>
		</employee>
		<employee position="Salesperson">
			<name>Jim Smith</name>
		</employee>
	</employees>;
alert(employees.employee[0].@position); //"Software Engineer"

alert(employees.employee[0].child("@position")); //"Software Engineer"

alert(employees.employee[0].attribute("position")); //"Software Engineer"

//下面两种方式都会取得所有特性
var atts1 = employees.employee[0].@*;
var atts2 = employees.employee[0].attributes();

employees.employee[0].@position = "Author"; //修改 position 特性

employees.employee[0].@experience = "8 years"; //添加 experience 特性
employees.employee[0].@manager = "Jim Smith"; //添加 manager 特性

delete employees.employee[0].@position; //删除 position 特性

    其他节点类型

    E4X 定义了表现 XML 文档中所有部分的类型,包括注释和处理指令。在默认情况上, E4X 不会解析注释或处理指令,因此这些部分不会出现在最终的对象层次中。如果想让解析器解析这些部分,可以设置 XML 构造函数的特定属性。

XML.ignoreComments = false;
XML.ignoreProcessingInstructions = false;

    查询

    E4X 提供的查询语法在很多方面都与 XPath 类似。取得元素或特性值的简单操作是最基本的查询。在查询之前,不会创建表现 XML 文档结构中不同部分的 XML 对象。从底层来看,XML 和 XMLList的所有属性事实上都是查询的结果。也就是说,引用不表现 XML 结构中某一部分的属性仍然会返回XMLList;只不过这个 XMLList 中什么也不会包含。

var cats = employees.cat;
alert(cats.length()); //0
var allDescendants = employees..*; //取得<employees/>的所有后代节点

var allNames = employees..name; //取得作为<employees/>后代的所有<name/>节点

var allDescendants = employees.descendants(); //所有后代节点
var allNames = employees.descendants("name"); //后代中的所有<name/>元素

var allAttributes = employees..@*; //取得所有后代元素中的所有特性
var allAttributes2 = employees.descendants("@*"); //同上

var allAttributes = employees..@position; //取得所有 position 特性
var allAttributes2 = employees.descendants("@position"); //同上

    构建和操作XML

var tagName = "color";
var color = "red";
var xml = <{tagName}>{color}</{tagName}>;
alert(xml.toXMLString()); //"<color>red</color>

    如果将一个值指定给一个不存在的元素或特性, E4X 就会首先在底层创建相应的结构,然后完成赋值。

var employees = <employees/>;
employees.employee.name = "Nicholas C. Zakas";
employees.employee.@position = "Software Engineer";
employees.employee += <employee position="Salesperson">
                    <name>Jim Smith</name>
                </employee>;
<employees>
	<employee position="Software Engineer">
		<name>Nicholas C. Zakas</name>
	</employee>
	<employee position="Salesperson">
		<name>Jim Smith</name>
	</employee>
</employees>

    解析和序列化

    E4X 将解析和序列化数据的控制放在了 XML 构造函数的一些设置当中。与 XML 解析相关的设置有如下三个。
ignoreComments:表示解析器应该忽略标记中的注释。默认设置为 true。
ignoreProcessingInstructions:表示解析器应该忽略标记中的处理指令。默认设置为 true。
ignoreWhitespace:表示解析器应该忽略元素间的空格,而不是创建表现这些空格的文本节点。默认设置为 true。
这三个设置会影响对传入到 XML 构造函数中的字符串以及 XML 字面量的解析。
另外,与 XML 数据序列化相关的设置有如下两个。
prettyIndent:表示在序列化 XML 时,每次缩进的空格数量。默认值为 2。
prettyPrinting:表示应该以方便人类认读的方式输出 XML,即每个元素重起一行,而且子元素都要缩进。默认设置为 true。
这两个设置将影响到 toString()和 toXMLString()的输出。

var settings = XML.settings();
alert(settings.ignoreWhitespace); //true
alert(settings.ignoreComments); //true

var settings = XML.settings();
XML.prettyIndent = 8;
XML.ignoreComments = false;
//执行某些处理
XML.setSettings(settings); //重置前面的设置

XML.setSettings(XML.defaultSettings());//⊥

    命名空间

var messages = <messages>
        <message>Hello world!</message>
    </messages>;
messages.setNamespace(new Namespace("wrox", "http://www.wrox.com/"));

//只添加一个命名空间声明,而不想改变元素
messages.addNamespace(new Namespace("wrox", "http://www.wrox.com/"));

//移除表示特定命名空间前缀和 URI的命名空间声明
messages.removeNamespace(new Namespace("wrox", "http://www.wrox.com/"));