`

flex(actionscript3.0)中E4x 和 XML的应用

阅读更多

下面是对图灵出版的XML and E4X 的一些章节翻译,供参考。

XML 和 E4X (FLASH 和 FLEX 中的应用)

第八章: 使用ActionScript 3.0来修改XML的内容

首先是基于Flash的例子:

对于Flash来说, 首先建立一个新的Flash ActionScript 3.0版的文档(as 3.0 fla),并且把authors.xml文件载入到名为authorsXML的XML变量中, 可以使用下面的代码来导入外部的XML内容到这个fla文件中。

var authorsXML:XML;
var request:URLRequest = new URLRequest(“authors.xml);
var loader:URLLoader = new URLLoader();
function initApp():void
{
   loader.addEventListener(Event.COMPLETE, completeHandler);
   loader.load(request);
}	
function completeHandler(e:Event):void
{
   authorsXML = XML(e.target.data);
   trace(authorsXML);
}
initApp();

 

基于Flex的例子:

你也可以通过Flex Builder来书写处理XML的代码, 新建一个Flex项目, 并且在src文件夹里面在新建一个assets文件夹,建立一个XML文档并把authors.xml放入这个文件夹中。(好习惯)。

然后使用<mx:XML>标签可以很容易的载入XML文档, 把下面这个语句放入到主应用程序文件里, 同时设置source属性来映射XML文档位置:

<mx:XML id=”authorsXML” source=”assets/authors.xml/>
<!--把createComplete 事件加入到<mx:Application>元素中去:-->
	creationComplete=”initApp(event)”;
添加下列语句块:
<mx:Script>
	<![CDATA[
	import mx.events.FlexEvent;
	private function initApp(e:FlexEvent):void
        {
	      //监听器方法		
        }
        ]]>
</mx:Script>


下面看下如何改变元素和属性值:

你可以很容易的改变元素和属性的值,但要记住你所做的修改, 仅仅只是修改了在SWF应用程序中XML的值, 修改不会影响到XML源数据, 说明你无法在同一时间更新一个外部XML文档或者是database。

你要更新元素和属性的值,首先要定位于相关的节点和属性, 然后在使用“=”(变量赋值符号)来指定新值。你可以使用E4X表达式, XML方法(Flash Player XML API), 或者2者(XML API 和 E4X)同时使用来创建指向目标元素或者属性的路径。

指定新值的过程是很直接的, 然而, 你构建的任何表达式必须返回一个单一的XML元素(However, you must remember that any expressions that you construct must return a single XML element)。如果一个表达式返回的是一个XMLList,那你就无法对这个表达式赋一个值, 在这种情况下, 你如果想在同一时间对多于一个XML的元素尝试赋一个单一值的话, 你会得到一个报错。

看看下面的这个方法, 我们要改变这个XML对象里面first author的名字(从Alision Ambrose 到 Alan Amberson), 这些值出现在第一个<author>元素里的<authorFirstName>和<authorLastName>元素中, 我们可以通过下面的代码对这些元素指定新值:

       authorsXML.author[0].authorFirstName = “Alan”;
       authorsXML.authro[0].authorLastName = “Amberson;


如果我们用trace()查看第一个<author>元素的值, 可以看到下面的变化.

       <authorFirstName>Alan</authorFirstName>
       <authorLastName>Amberson</authorLastName>

我们已经在这2个元素中成功更新了它们的值!!

我们也可以使用replace() 方法为一个元素指定一个新值:(这个是Flash XML API中的方法)

       authorsXML.author[0].replace(“authorFirstName”,”<authorFirstName>Alan</authorFirstName>);


注意方法的第一个参数指定了我们想要替换的位置, 在这里是<authorFirstName>元素, 第二个参数提供了替换内容, 在这里是<authorFirstName>Alan</authorFirstName>。需要注意第二个参数需要开关括号(opening and closing tags).

比起使用简单的赋值符号, replace()方法明显要麻烦很多…., 然而, 这个方法可以让你指定不同的元素结构来使用(作为替换体)。使用它, 完全可以把<authorFirstName>元素替换为一个完全不同的一组元素(a completely different set of elements). 修改属性值同样很简单, 举个例子, 我们可以改变第一个author元素的authorID属性值:

       authorsXML.author[0].@authorID =”99”;
	trace第一个<author>元素的值会得到如下结果:
       authorsXML.author[0].@authorID =”99”;

我们成功的改变了属性的值!!!

我们同样可以同时在一个时间段里面改变多个值, 你可以修改多个元素或者属性通过迭代集合来分别得到其中的每一项。 举个例子: 在每个authorID属性值的前面加上数字10:

for each(var aXML:XML in authorsXML.author)
{
    aXML.@authorID = “10”+ aXML.@authorID;
}

以上演示了使用for each语句来迭代每个<author>元素中的XML对象, 你可以分开的独自处理它们。 Trace这个XML实例, 得到树型结构。

      <author authorID=”101>
      <author authorID=”102>
      <author authorID=”103>
      <author authorID=”104>

下一节我们看下XML类中的方法如何修改XML文档的结构.(XML API).

 

添加, 编辑, 删除XML内容

现在介绍一些如何修改现有的XML对象的结构的一些方法(XML API), 下面是一些总结:

用于修改XML内容的XML类方法

方法:
appendChild(child)				  在所确定的所有节点之后加入指定的子节点
 
copy()                                            对现有的节点来份拷贝
 
insertChildAfter(child1, child2)                  在指定的节点后插入一个新子节点
 
insertChildBefore(child1, child2)                 在指定的节点前插入一个新子节点
 
prependChild(value)				  在所确定的节点的最前方加入指定的子节点
 
replace(propertyName, value)                      根据提供的值, 替换指定的属性, 或者元素.
 
(replaces a spedifed property, perhaps an element or attribute, with the provided value)
 
 
setChildren(value)                  根据指定的内容来替换一个XML对象的子项。

下面我们要依次演示一下这些方法的细节, 我们下面从appendChild()方法开始.

使用appendChild()

appendChild()方法在现有的子节点序列的后面添加一个新的子节点, 它需要一个参数, 就是你想添加的子项, 作为最后的子项目添加, 下面是个例子:

var newAuthor:XML = 
<author id=”5>
     <authorFirstName>Sas</authorFirstName>
     <authorLastName>Jacobs</authorLastName>
</author>
authorsXML.appendChild(newAuthor);


这段代码首先创建了新的XML对象叫做newAuthor. 然后添加了一些节点的细节, 包含了文本节点和属性,最后一行通过authorsXML(the root element)调用了appendChild()方法, 方法中传入了新的XML对象, trace authorsXMl 对象后可以看到新节点已处于<allAuthors>节点的最后, 最后的XML对象如下显示.

<author id=”5>
     <authorFirstName>Sas</authorFirstName>
     <authorLastName>Jacobs</authorLastName>
</author>

appendChild()方法能够在XML对象的任意节点处添加新的子元素, (It doesn’t need to refer to the root element.) 下面的代码显示了如何在第二个<author>元素节点中加入一个新的book子节点.

       var newBook:XML = 
           <book bookID=“10>
	      <bookName>Hearty Soups</bookName>
	      <bookPublishYear>2008</bookPublishYear>
           </book>
       authorsXML.author[1].books.appendChild(newBook);
       authorsXML.author[1] 返回XML
       authorsXML.author[1].books 返回XMLList (尽管只有一个XML子项)
       authorsXML.author[1].books[0] 返回XML(指定了具体位置了)


上述这些E4X方法就相当于XML API和XMLList API 中的 child(), children()方法,它们返回的都是XMLList形式.


运行后, 发现运作正常, newBook被正确插入, 但在这里注意, 查看FLASH PLAYER API, appendChild()方法属于XML类实例方法, XMLList类没有这个方法, authorsXML.author[1].books这句返回的是一个XMLList对象, 可以用 is 关键字查看它返回的的确是一个XMLList, 但在这里为什么没有报错, 我的理解是返回的类型是XMLList, 它是相对于父XML对象而言的, 但是它本身的结构却是符合XML特征的(有主节点(root element), 正确的开闭符号), 比如:

 

var XML:XML = 
       <root>
	   <book1>AS Book</book1>
	   <book2>JAVA Book</book2>
       </root>

这是一个标准的XML结构, 如果执行trace(XML.children()); 来返回它的所有子项。

帮助: children () 方法 AS3 function children():XMLList 返回的是XMLList类型,

<book1>AS Book</book1>
<book2>JAVA Book</book2>

这2个返回相对于主节点来说就是2个XMLList对象, 2者没有共同的主节点, 好比2个毫无关联的对象(list), 2者并未包含在一个总的节点内, 但是2者从各自独立的角度来看的话, 它们都是标准的XML结构, 拥有各自的主节点(root element), 正确的开闭符号。

因此,上面的appendChild是允许的, 尽管trace出的信息是XMLList。(真正执行的是list中的一个对象), 这里E4X 自动 把 XMLList转换成XML了

如果你对XMLList(list)使用appendChild, 那会得到运行时报错,

	TypeError: Error #1086: appendChild 方法只能用于包含单一项目的列表。
	由于XML和XMLList内置类都是动态类, 可能导致在排查错误时的”困惑”;

当然你也可以不使用变量作为参数代入appendChild方法, 而是直接把XML结构放入appendChild参数中去:

authorsXML.author[1].books.appendChild(<book bookID=“10>
	<bookName>Hearty Soups</bookName>
	<bookPublishYear>2008</bookPublishYear>
</book>
);

这很直接, 但是容易搞混代码, 作者的经验是独自的去创建子元素(My preference is to create the Child element separately,),这可以让代码更容易阅读, 我们同样可以通过点号来设置属性一样的来设置新的XML对象的子元素, 就像下面一样,

var newBook:XML = <book bookID=“10></book>
newBook.bookName = Hearty Soups
newBook.bookPublishYear = 2008

上述是添加文本节点(text node), 如果是添加属性attribute,使用@符号 newBook.@id = “BookId”;


这种书写方法是替代了XML的结构,XML对象就像是定义属性一样定义它的自己的子元素, 可以和使用XML API 方法 创建子节点得到同样的结果.


删除一个元素你能使用delete()这种ActionScript 运算符来删除内容, 下面的例子演示了从 AuthorsXML对象中删除第一个<author>节点:

	delete(authorsXML.author[0]);

它删除了一个XML对象, 当然也可以删除XMLList对象, 比如:

	delete(authorsXML.*);

注意delete()并不是XML对象的一种方法, 实际上, 它是一个ActionScript3.0的运算符, 被使用在“合适的地方”,而不是单单为XML内容而工作的.(看了帮助上说的, 它用于删除对象的动态属性)。

比如:

var mc:MovieClip = new MovieClip();
mc.hello = "this is test";
trace(mc.hello);//this is test
delete(mc.hello);//删除动态属性
trace(mc.hello);//undefined

修改元素的名称和命名空间 还记得一个命名空间是和一个独有的URI相关联的元素吗?(Remember that a namespace associates an element with a particular URI).它可以确保你在一个XML对象中的每个元素和属性的名称是独一无二的(就算你给它们起的都是同样的名字)。添加一个命名空间: 你可以对一个XML对象使用addNamespace()方法来添加一个命名空间, 方法的参数就是你想添加的命名空间, 你可以通过一个Namespace对象或者QName对象来提供这个参数.

	<allAuthors xmlns:sj=http://www.sasjacobs.com/ns/ xmlns:aa=”http://www.alisonambrose.com/ns/”>

上面是2个命名空间, 下面在添加一个命名空间:

 
var ns:Namespace = new Namespace(‘foe’,”http://www.foe.com/ns/”);
authorsXML.addNamespace(ns);

上述代码创建了一个有着前缀foe和它所映射的URI的那么一个Namespace对象, 然后使用addNamespace()方法在主节点上添加了这个namespace属性. 在主节点上添加的命名空间意味着它可以应用于任何子元素。 当然添加属性并不只是在主节点上的, 同样可以在任何子元素上添加, 比如:

 
	authorsXML.author[0].books.addNamespace(ns);

同样的, 你可以从一个现有元素的命名空间中吸取现成的命名空间, 来应用于其它的元素, 比如:

 
	<author authorID=”4”xmlns:ss=http://www.saulsorenson.com/us/>
	var ss:Namespace = authorXML.author[3].namespace(“ss”);
	authorsXML.author[1].addNamespace(ss);

<!-- /bodytext --><!-- catlinks -->

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics