xml 对象
XML 对象
XML 对象表示 XML 树中的 XML 元素节点。XML 文件的顶层 XML
对象表示根节点。它充当一个列表,其中包含每个元素的附加 XML
对象。这些对象又包含它们自己的成员元素的 XML 对象,依此类推。
元素树的子元素作为父元素的 XML
对象的属性可用。属性的名称对应于元素的名称。每个属性包含一个 XML
对象数组,每个对象表示一个命名类型的元素。
例如,假设你有以下最小的 XML 代码:
<rootElement> <elementA> <elementB></elementB> </elementA> <elementA> <elementB></elementB> </elementA></rootElement>
在 JavaScript 脚本中,你从此 XML 代码创建的 XML 对象表示根元素:
var myRoot = new XML( "<rootElement> <elementA> <elementB></elementB> </elementA> <elementA> <elementB></elementB> </elementA> </rootElement>");
你可以直接将常量分配给 XML 值。以下隐式创建了分配给 myRoot
的 XML 对象:
var myRoot = <rootElement> <elementA> <elementB></elementB> </elementA> <elementA> <elementB></elementB> </elementA></rootElement>;
对象 myRoot
包含一个名为 elementA
的属性,该属性包含两个 XML
对象,分别表示该元素的两个实例。每个对象又包含一个 elementB
属性,该属性包含一个空的 XML
对象:
var elemB1 = myRoot.elementA[0].elementB[0];
如果 XML 中的元素为空,则相应的属性存在并包含一个空的 XML 对象;它永远不会是 null
或 undefined
。
访问 XML 元素
本章中的示例使用以下示例 XML 代码:
<bookstore> <book category="COOKING"> <title lang="en">The Boston Cooking-School Cookbook</title> <author>Fannie Merrit Farmer</author> <year>1896</year> <price>49.99</price> </book> <book category="CHILDREN"> <title lang="en">The Wonderful Wizard of Oz</title> <author>L. Frank Baum</author> <year>1900</year> <price>39.95</price> </book> <book category="CHILDREN"> <title lang="en">Alice's Adventures in Wonderland</title> <author>Charles "Lewis Carroll" Dodgeson</author> <author>Charles Dodgeson</author> <author>Lewis Carroll</author> <year>1865</year> <price>29.99</price> </book> <book category="MUSIC"> <title lang="en">Gilbert and Sullivan Opera; A History and a Comment</title> <author>H. M. Walbrook</author> <year>1922</year> <price>30.00</price> </book></bookstore>
要将此代码封装在 XML 对象中,将其序列化为字符串并将该字符串传递给构造函数:
var bookXmlStr = "...";var bookstoreXML = new XML (bookXmlStr);
使用此示例,根元素 <bookstore>
由构造函数返回的 XML 对象表示。每个 <book>
元素作为 XML 对象的 book
属性的成员可用。
- JavaScript 语句
bookstoreXML.book;
返回所有书籍的列表。 - 语句
bookstoreXML.book[0];
返回第一本书的XML
对象。 - 语句
bookstoreXML.book[0].author;
返回第一本书的所有作者。
有关访问树中元素的更多方法,请参阅 检索包含的元素 和 创建和访问命名空间。
访问 XML 属性
属性是其父元素的属性。在 ExtendScript 中,通过在属性名称前加上 at 符号 (@
) 来访问属性名称。属性属性是一个单元素列表,其中包含属性值的 XML 对象。例如:
bookstoreXML.book [0].@category;
这将返回第一本书的 category
属性,其值为字符串 "COOKING"
。
要访问所有书籍的所有 category
属性,请使用以下语句:
bookstoreXML.book.@category
你可以使用以下形式的谓词引用具有特定属性值的一组元素:
element.(@attribute == value)
例如,此语句仅返回具有 category
属性且值为 "CHILDREN"
的书籍元素:
bookstoreXML.book.(@category == "CHILDREN");
查看 XML 对象
XML 对象与所有 ExtendScript 对象一样,具有 toString
方法,该方法将内容序列化为字符串。在这种情况下,字符串仅包含元素的文本内容,而不包含标签。例如,对于元素 <x>text</x>
,toString()
方法返回 "text"
。
当你在 ExtendScript Toolkit 的 JavaScript 控制台中评估对象时,会调用此方法。它会重新创建对象封装的 XML 文本。因此,如果你在控制台中评估对象 bookstoreXML.book[1]
,你将看到封装的树的 XML 文本,格式化为带有换行符和空格:
> bookstoreXML.book[1]; <book category="CHILDREN"> <title lang="en">The Wonderful Wizard of Oz</title> <author>L. Frank Baum</author> <year>1900</year> <price>39.95</price> </book>
如果你评估具有文本值的对象,你将看到文本值。例如:
> bookstoreXML.book[1].@category; CHILDREN
如果你访问多个值,这些值将被连接起来:
> bookstoreXML.book.@category COOKINGCHILDRENCHILDRENMUSIC
toXMLString() 方法将整个元素(包括标签)序列化为字符串。
例如,对于元素 <x>text</x>
,该方法返回 "<x>text</x>"
。
修改 XML 元素和属性
你可以通过为相应属性赋值来更改元素。
- 如果分配的值是 XML 元素,则元素将被替换。如果有多个相同类型的元素,则第一个元素将被替换,所有其他元素将被删除。
- 如果分配的值不是 XML,则将其转换为字符串,并用该字符串替换元素的内容。
- 如果不存在此类型的元素,则会将新元素附加到 XML 中。
你可以使用相同的技术更改属性的值。
修改示例
在示例 XML 中,第三本书有多个 <author>
元素。此语句将所有元素替换为包含新字符串的单个元素:
bookstoreXML.book[2].author = "Charles 'Lewis Carroll' Dodgeson";
结果是以下 XML:
<book category="CHILDREN"> <title lang="en">Alice's Adventures in Wonderland</title> <author>Charles 'Lewis Carroll' Dodgeson</author> <year>1865</year> <price>29.99</price></book>
要仅替换第一个作者,保留所有其他作者,请使用以下语句:
bookstoreXML.book[2].author[0] = "Charles Dodgeson, aka Lewis Carroll";
此语句更改第二本书中 <year>
元素的内容。ExtendScript 会自动将数值转换为字符串:
bookstoreXML.book[1].year = 1901;
以下语句向第二本书添加一个新的 <rating>
元素:
> bookstoreXML.book[1].rating = "**\***";
结果是以下 XML:
<book category="CHILDREN"> <title lang="en">The Wonderful Wizard of Oz</title> <author>L. Frank Baum</author> <year>1900</year> <price>39.95</price> <rating>*****</rating></book>
此语句更改第二本书的 category
属性的值:
bookstoreXML.book[1].@category = "LITERATURE, FANTASY"
结果是以下 XML:
<book category="LITERATURE, FANTASY"><title lang="en">The Wonderful Wizard of Oz</title>...
删除元素和属性
要删除 XML 中的元素或属性,请使用 JavaScript 的 delete
运算符删除相应的元素或属性属性。如果元素有多个实例,你可以删除所有实例,或通过索引引用单个实例。
删除示例
此语句删除第三本书的所有作者:
delete bookstoreXML.book[2].author;
此语句仅删除第三本书的第二个作者:
delete bookstoreXML.book[2].author[1];
此语句删除第三本书的 category
属性:
delete bookstoreXML.book[2].@category;
检索包含的元素
XML
对象提供了允许你检索树中不同级别包含的元素的方法:
-
XML.
children() 获取直接子元素,包括文本元素。 -
XML.
elements() 获取直接子元素中的 XML 标签,但不获取文本。 -
XML.
descendants() 允许你匹配特定标签,并获取任何嵌套级别的所有匹配元素。你还可以使用“双点”符号访问元素的后代。例如,以下语句是等效的:xml..titlexml.descendants("title")
例如,考虑以下 XML 代码加载到名为 x
的顶层 XML
对象中:
<top> <one>one text</one> <two> two text <inside>inside text</inside> </two> top text</top>
以下是不同调用的结果。
-
XML.
children() 的结果包含 3 个元素,直接子标签<one>
和<two>
,以及<top>
标签的直接包含文本:**> x.children()**<one>one text</one><two>two text<inside>inside text</inside></two>top text**> x.children().length()**3 -
XML.
elements() 的结果包含 2 个元素,直接子标签<one>
和<two>
:**> x.elements()**<one>one text</one><two>two text<inside>inside text</inside></two>**> x.elements().length()**2 -
XML.
descendants() 的结果包含 7 个元素,直接子标签<one>
和<two>
,下一级的<inside>
标签,以及所有标签的文本内容:**> x.descendants()**<one>one text</one>one text<two>two text<inside>inside text</inside></two>two text<inside>inside text</inside>inside texttop text**> x.descendants().length()**7
创建和访问命名空间
简单的访问语句访问默认命名空间中的元素。如果你需要在多个命名空间中定义元素,则必须使用 Namespace 对象 来访问不在默认命名空间中的任何元素。
在树中定义命名空间
你可以使用 xmlns
属性在 XML 元素中定义命名空间,并将模式中的元素定义为属于该命名空间。例如,以下示例 XML 的添加定义了一个命名空间,将前缀 “kids” 映射到命名空间 “http://kids.mybookstore.com”,然后使用该前缀将特定书籍元素放置在该命名空间中:
<bookstore **xmlns:kids="http://kids.mybookstore.com"**>
<book category="COOKING"> <title lang="en">The Boston Cooking-School Cookbook</title> <author>Fannie Merrit Farmer</author> <year>1896</year> <price>49.99</price></book>
<**kids:**book category="CHILDREN"> <title lang="en">The Wonderful Wizard of Oz</title> <author>L. Frank Baum</author> <year>1900</year> <price>39.95</price></**kids:**book>...
定义此命名空间后,简单的语句 bookstoreXML.book
不再返回 “The Wonderful Wizard of Oz”,因为该书不再位于默认命名空间中。要访问该书,你必须为命名空间定义一个 Namespace 对象,并使用它来访问元素。
例如,以下 JavaScript 代码为 <bookstore>
元素中定义的命名空间创建了一个 Namespace 对象,并通过该对象访问命名空间中的书籍:
var ns = new Namespace ("http://kids.mybookstore.com");bookstoreXML.ns::book;
设置默认命名空间
默认情况下,默认命名空间是一个 URI 为空字符串的命名空间。可以设置默认命名空间;在这种情况下,简单的访问器访问该命名空间中的元素。
要设置默认命名空间,请使用全局函数 setDefaultXMLNamespace(),或以下语法:
default xml namespace = namespace_specifier;
命名空间说明符可以是 Namespace 对象 或 URL 字符串。例如:
default xml namespace = "http://books.mybookstore.com";
设置默认命名空间后:
- 默认命名空间中的元素(因此可以通过简单访问器访问)必须使用命名空间前缀。
- 所有没有特定命名空间分配的元素都位于空命名空间中,而不是默认命名空间中。要访问它们,你必须使用 URI 为空字符串的 Namespace 对象。
访问命名空间中的元素
-
你可以直接访问默认命名空间中的元素,而无需使用 Namespace 对象。
- 如果你没有设置默认值,则可以对没有命名空间说明符的元素使用直接访问。
- 如果你设置了默认值,则可以对位于该命名空间中的元素使用直接访问。
-
如果你已将元素分配给命名空间,并且未将其设置为默认值,则必须使用 Namespace 对象 来访问这些元素。例如:
var ns = new Namespace (**"http://kids.mybookstore.com"**);bookstoreXML.**ns::book**;这将返回所有已分配给 “kids” 命名空间的书籍。
-
如果你设置了默认命名空间,你仍然可以通过使用 URI 为空字符串的 Namespace 对象 来访问所有没有特定命名空间分配的对象,这是默认创建情况:
var emptyNS = new Namespace ();bookstoreXML.emptyNS::book;这将返回所有未分配给任何命名空间的书籍。
-
要访问所有元素,无论命名空间分配如何,你可以使用星号 (*) 通配符或
null
作为命名空间名称:bookstoreXML.*::book;或
var nullNS = null;bookstoreXML.nullNS::book;
混合 XML 和 JavaScript
你可以将 JavaScript 语句括在花括号中,并将其嵌入到 XML 中。JavaScript 部分在 XML 构造期间被评估。
例如,此函数返回一个 XML 值,其中嵌入的 JavaScript 变量将被评估并包含在内:
function makeXML (first, last) { return <person first={first} last={last}>{first + " " + last}</person>;}
调用此函数:
makeXML ( "Jane", "Doe" );
结果是以下 XML:
<person first="Jane" last="Doe">Jane Doe</person>
你还可以在 XML 元素上使用这些运算符:
- 使用加号运算符
+
将 XML 元素组合成一个列表。 - 使用
==
运算符对两个 XML 树进行深度比较。
XML 列表
ExtendScript 定义了一个 XMLList
对象,它与 XML 对象 相同,只是你可以通过传递 XML 列表来创建它,并且它创建的是 XML 列表而不是 XML 标签。
所有收集 XML 的 XML 语句和函数都将结果作为 XMLList
返回,如果没有匹配项,则可以为空。例如,以下语句返回一个空列表:
bookstoreXML.magazine;