1、E4X的类型
1.1 XML类型
1、创建XML对象的方法
:
(1)调用构造函数:
var x = new XML();
var x = new XML("<employee position=\"Software Engineer\"><name>Nicholas " +"Zakas</name></employee>");
(2)使用 XML 字面量将XML数据直接指定给一个变量。XML字面量就是嵌入到JavaScript代码中的XML代码。
var employee = <employee position="Software Engineer">
<name>Nicholas C. Zakas</name>
</employee>;
2、XML 类型的toXMLString()方法
会返回 XML 对象及其子节点的 XML 字符串表示。另一方面,该类型的 toString()方法
则会基于不同 XML 对象的内容返回不同的字符串。
var data = <name>Nicholas C. Zakas</name>;
alert(data.toString()); //"Nicholas C. Zakas"
alert(data.toXMLString()); //"<name>Nicholas C. Zakas</name>"
1.2 XMLList类型
XMLList 类型表现 XML 对象的有序集合。 XMLList 的 DOM 对等类型是 NodeList。
1、创建XMLList对象的方法
:
(1)可以向其中传入一个待解析的 XML 字符串;
var list = new XMLList("<item/><item/>");
(2)还可以使用加号( +)操作符来组合两个或多个 XML 对象,从而创建 XMLList 对象。
var list = <item/> + <item/> ; //这个例子使用加号操作符组合了两个 XML 字面量,结果得到一个 XMLList。
2、每个 XMLList 对象都有 length()方法
,用于返回对象中包含的元素数量。
alert(employees.employee.length()); //2
(3)XMLList 对象的 toString()和 toXMLString()方法返回相同的字符串值,也就是将其包含的XML 对象序列化之后再拼接起来的结果。
1.3 Namespace类型
使用 Namespace 对象来表现命名空间。通常, Namespace 对象是用来映射命名空间前缀和命名空间 URI 的。
1、创建Namespace对象的方法
:
(1)使用 Namespace构造函数,传入 URI 或前缀加 URI,就可以初始化 Namespace 对象
var ns = new Namespace();
var ns = new Namespace("http://www.wrox.com/"); //没有前缀的命名空间
var wrox = new Namespace("wrox", "http://www.wrox.com/"); //wrox 命名空间
(2)通过 XML 构造函数解析的 XML 字符串中包含命名空间信息,那么就会自动创建 Namespace 对象。然后,就可以通过前缀和namespace()方法
来取得对 Namespace
对象的引用。
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);
2、可以使用 prefix 和 uri 属性来取得 Namespace 对象中的信息
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"
3、Namespace 对象的 toString()方法始终会返回命名空间 URI
1.4 QName类型
QName 类型表现的是 XML 对象的限定名,即命名空间与内部名称的组合。
1、创建 QName对象的方法
:
(1)向 QName 构造函数中传入名称或 Namespace 对象和名称,可以手工创建新的 QName 对象。
var wrox = new Namespace("wrox", "http://www.wrox.com/");
var wroxMessage = new QName(wrox, "message"); //表示"wrox:message"
创建了 QName 对象之后,可以访问它的两个属性: uri 和 localName。其中,uri属性返回在创建对象时指定的命名空间的 URI(如果未指定命名空间,则返回空字符串),而 localName 属性返回限定名中的内部名称。
alert(wroxMessage.uri); //"http://www.wrox.com/"
alert(wroxMessage.localName); //"message"
(2)在解析 XML 结构时,会为表示相应元素或特性的 XML 对象自动创建 QName 对象。可以使用这个 XML对象的name()方法
取得与该XML对象关联的 QName 对象。
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"
2、(1)使用 setName()方法并传入一个新 QName 对象,可以修改 XML 对象的限定名。
xml.setName(new QName("newroot"));
(2)如果该名称不属于任何命名空间,则可以像下面这样使用 setLocalName()方法来修改内部名称。
xml.setLocalName("newtagname");
2、一般用法
1、使用点号加特性或标签名的方式
来访问其中不同的层次和结构。每个子元素都是父元素的一个属性,而属性名与元素的内部名称相同。
var employee = <employee position="Software Engineer">
<name>Nicholas C. Zakas</name>
</employee>;
alert(employee.name); //"Nicholas C. Zakas"、
2、如果你不确定子元素的内部名称,或者你想访问所有子元素,不管其名称是什么,也可以像下面这样使用星号( *)
。
var allChildren = employees.*; //返回所有子元素,不管其名称是什么
alert(employees.*[0].name); //"Nicholas C. Zakas"
3、还可以使用 child()方法
。将属性名或索引值传递给 child()方法,也会得到相同的值。
var firstChild = employees.child(0); //与 employees.*[0]相同
var employeeList = employees.child("employee"); //与 employees.employee 相同
var allChildren = employees.child("*"); //与 employees.*相同
4、为了再方便一些,还有一个children()
方法始终返回所有子元素;
var allChildren = employees.children(); //与 employees.*相同
5、方法 elements()
的行为与 child()类似,区别仅在于它只返回表示元素的 XML对象。
var employeeList = employees.elements("employee"); //与 employees.employee 相同
var allChildren = employees.elements("*"); //与 employees.*相同
6、要删除子元素,可以使用 delete
操作符
elete employees.employee[0];
alert(employees.employee.length()); //1
2.1 访问特性
1、访问特性的三种方法:
(1)访问特性也可以使用点语法
,不过其语法稍有扩充,必须在名称前面加上一个@字符。
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"
(2)使用child()方法
来访问特性,只要传入带有@前缀的特性的名称即可
alert(employees.employee[0].child("@position")); //"Software Engineer"
(3)使用attribute()方法
并传入特性名,可以只访问 XML 对象的特性。与 child()方法不同,使用 attribute()方法时,不需要传入带@字符的特性名。
alert(employees.employee[0].attribute("position")); //"Software Engineer"
2、要取得 XML 或 XMLList 对象中的所有特性,可以使用attributes()方法。这个方法会返回一个表示所有特性的 XMLList 对象。使用这个方法与使用@*的结果相同,如下面的例子所示。
//下面两种方式都会取得所有特性
var atts1 = employees.employee[0].@*;
var atts2 = employees.employee[0].attributes();
3、对特性的操作
(1)修改
employees.employee[0].@position = "Author"; //修改 position 特性
(2)增加
employees.employee[0].@experience = "8 years"; //添加 experience 特性
employees.employee[0].@manager = "Jim Smith"; //添加 manager 特性
(3)删除
delete employees.employee[0].@position; //删除 position 特性
2.2 其他节点类型
1、E4X定义了表现XML文档中所有部分的类型,包括注释和处理指令。在默认情况上,E4X不会解析注释或处理指令,因此这些部分不会出现在最终的对象层次中。如果想让解析器解析这些部分,可以像下面这样设置XML构造函数的下列两个属性。
XML.ignoreComments = false;
XML.ignoreProcessingInstructions = false;
//在设置了这两个属性之后, E4X 就会将注释和处理指令解析到 XML 结构中。
2、使用nodeKind()方法
可以得到 XML 对象表示的类型,该访问可能会返回"text"、 "element"、 "comment"、"processinginstruction"或"attribute"。
3、可以只取得特定类型的节点,而这就要用到下列方法:
- attributes():返回 XML 对象的所有特性。
- comments():返回 XML 对象的所有子注释节点。
- elements(tagName):返回 XML 对象的所有子元素。可以通过提供元素的 tagName(标签名)来过滤想要返回的结果。
- processingInstructions(name):返回 XML 对象的所有处理指令。可以通过提供处理指令的 name(名称)来过滤想要返回的结果。
- text():返回 XML 对象的所有文本子节点。
4、使用hasSimpleContent()
和 hasComplexContent()
方法, 可以确定 XML 对象中是只包含文本,还是包含更复杂的内容。如果 XML 对象中只包含子文本节点,则前一个方法会返回 true;如果XML对象的子节点中有任何非文本节点,则后一个方法返回 true。来看下面的例子。
alert(employees.employee[0].hasComplexContent()); //true
alert(employees.employee[0].hasSimpleContent()); //false
alert(employees.employee[0].name.hasComplexContent()); //false
alert(employees.employee[0].name.hasSimpleContent()); //true
2.3 查询
1、像下面这样使用两个点,则可以进一步扩展查询的深度,查询到所有后代节点。
var allDescendants = employees..*; //取得<employees/>的所有后代节点
2、使用 descendants()方法来完成。在不给这个方法传递参数的情况下,它会返回所有后代节点(与使用..*相同),而传递一个名称作为参数则可以限制结果。
var allDescendants = employees.descendants(); //所有后代节点
var allNames = employees.descendants("name"); //后代中的所有<name/>元素
3、可以取得所有后代元素中的所有特性,方法是使用下列任何一行代码。
var allAttributes = employees..@*; //取得所有后代元素中的所有特性
var allAttributes2 = employees.descendants("@*"); //同上
4、完整的特性名来替换星号达到过滤特性的目的
var allAttributes = employees..@position; //取得所有 position 特性
var allAttributes2 = employees.descendants("@position"); //同上
5、除了访问后代元素之外,还可以指定查询的条件。
返回 position 特性值为"Salesperson"的所有<employee/>元素,可以使用下面的查询:
var salespeople = employees.employee.(@position == "Salesperson");
6、使用parent()
方法能够在 XML 结构中上溯,这个方法会返回一个 XML 对象,表示当前 XML 对象的父元素。如果在 XMLList 上调用 parent()方法,则会返回列表中所有对象的公共父元素。
var employees2 = employees.employee.parent();
2.4 构建和操作XML
1、将 XML 数据转换成XML对象的方式:
(1)将 XML 字符串传递到XML构造函数中;
(2)使用 XML 字面量;
2、除了上面介绍的基本的 XML 构建语法之外,还有一些类似 DOM 的方法,简介如下。
- appendChild(child):将给定的 child 作为子节点添加到 XMLList 的末尾。
- copy():返回 XML 对象副本。
- insertChildAfter(refNode, child):将 child 作为子节点插入到 XMLList 中 refNode 的后面。
- insertChildBefore(refNode, child):将 child 作为子节点插入到 XMLList 中 refNode 的前面。
- prependChild(child):将给定的 child 作为子节点添加到 XMLList 的开始位置。
- replace(propertyName, value):用 value 值替换名为 propertyName 的属性,这个属性可能是一个元素,也可能是一个特性。
- setChildren(children):用 children 替换当前所有的子元素, children 可以是 XML 对象,也可是 XMLList 对象。
2.5 解析和序列化
E4X 将解析和序列化数据的控制放在了 XML 构造函数的一些设置当中。
1、与 XML 解析相关的设置有如下三个。
- ignoreComments:表示解析器应该忽略标记中的注释。默认设置为 true。
- ignoreProcessingInstructions: 表示解析器应该忽略标记中的处理指令。默认设置为 true。
- ignoreWhitespace:表示解析器应该忽略元素间的空格,而不是创建表现这些空格的文本节点。默认设置为 true。
这三个设置会影响对传入到 XML 构造函数中的字符串以及 XML 字面量的解析。
2、另外,与 XML 数据序列化相关的设置有如下两个。
- prettyIndent:表示在序列化 XML 时,每次缩进的空格数量。默认值为 2。
- prettyPrinting:表示应该以方便人类认读的方式输出 XML,即每个元素重起一行,而且子元素都要缩进。默认设置为 true
以上五个设置都保存在 settings 对象中,通过 XML 构造函数的 settings()方法可以取得这个对象
var settings = XML.settings();
alert(settings.ignoreWhitespace); //true
alert(settings.ignoreComments); //true
3、使用 defaultSettings()方法则可以取得一个包含默认设置的对象,因此任何时候都可以使用下面的代码重置设置。
XML.setSettings(XML.defaultSettings());
2.6 命名空间
1、调用 setNamespace()方法后,相应的命名空间只会应用到调用这个方法的元素;
2、如果只想添加一个命名空间声明,而不想改变元素,可以使用 addNamespace()方法并传入Namespace 对象;
3、调用 removeNamespace()方法并传入 Namespace 对象,可以移除表示特定命名空间前缀和 URI的命名空间声明;注意,必须传入丝毫不差的表示命名空间的 Namespace 对象;
4、有两个方法可以返回与节点相关的 Namespace 对象的数组: namespaceDeclarations()和inScopeNamespaces()。 namespaceDeclarations()返回在给定节点上声明的所有命名空间的数组,inScopeNamespaces()返回位于给定节点作用域中(即包括在节点自身和祖先元素中声明的)所有命名空间的数组。
5、使用双冒号( ::)也可以基于 Namespace 对象来查询 XML 结构中具有特定命名空间的元素。例如,要取得包含在 wrox 命名空间中的所有<message/>元素,可以参考下面的代码。
var messages = <messages xmlns:wrox="http://www.wrox.com/">
<wrox:message>Hello world!</message>
</messages>;
var wroxNS = new Namespace("wrox", "http://www.wrox.com/");
var wroxMessages = messages.wroxNS::message;
这里的双冒号表示返回的元素应该位于其中的命名空间。注意,这里使用的是 JavaScript 变量,而不是命名空间前缀。
6、可以为某个作用域中的所有 XML 对象设置默认命名空间。为此,要使用 default xml namespace语句,并将一个 Namespace 对象或一个命名空间 URI 作为值赋给它。
3、其他变化
1、引入了for-each-in 循环,以便迭代遍历每一个属性并返回属性的值。
2、4X 还添加了一个全局函数,名叫 isXMLName()。这个函数接受一个字符串,并在这个字符串是元素或特性的有效内部名称的情况下返回 true。在使用未知字符串构建 XML 数据结构时,这个函数可以为开发人员提供方便。
alert(isXMLName("color")); //true
alert(isXMLName("hello world")); //false
3、E4X 对标准 ECMAScript 的最后一个修改是 typeof 操作符。在对 XML 对象或 XMLList 对象使用这个操作符时, typeof 返回字符串"xml"。但在对其他对象使用这个操作符时,返回的都是"object".
4、全面启用E4X
要想完整地启用 E4X,需要将<script>标签的 type 特性设置为"text/javascript;e4x=1",例如:
<script type="text/javascript;e4x=1" src="e4x_file.js"></script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。