Flex As3 解析XML文件(上:基本操作)

最近使用Flex+As3做了一个类似于XML解析的小程序,现将使用Flex解析XML文件的方法总结如下(本片文章好多地方参考于http://hdxiong.iteye.com/blog/580136):

首先带解析的XML文件:

  1. <WorkFlow>  
  2.   <Route ID="17" Name="" FromElementID="7" ToElementID="4"/>  
  3.   <Route ID="16" Name="" FromElementID="6" ToElementID="4"/>  
  4.   <Route ID="15" Name="" FromElementID="1" ToElementID="3"/>  
  5.   <Route ID="14" Name="" FromElementID="12" ToElementID="2"/>  
  6.   <Route ID="13" Name="" FromElementID="4" ToElementID="12"/>  
  7.   <Route ID="11" Name="" FromElementID="5" ToElementID="4"/>  
  8.   <Route ID="10" Name="" FromElementID="3" ToElementID="5"/>  
  9.   <Route ID="9" Name="" FromElementID="3" ToElementID="6"/>  
  10.   <Route ID="8" Name="" FromElementID="3" ToElementID="7"/>  
  11.   <Node type="BeginNode" ID="1" x="457" y="55">  
  12.     <Name>开始</Name>  
  13.   </Node>  
  14.   <Node type="EndNode" ID="2" x="469" y="666">  
  15.     <Name>结束</Name>  
  16.   </Node>  
  17.   <Node type="ForkNode" ID="3" x="465" y="190">  
  18.     <Name>分支</Name>  
  19.   </Node>  
  20.   <Node type="JoinNode" ID="4" x="455" y="464">  
  21.     <Name>合并</Name>  
  22.   </Node>  
  23.   <Node type="TaskNode" ID="5" y="330" x="458" taskNum="2">  
  24.     <Name>照明</Name>  
  25.     <NodeTyle>收费</NodeTyle>  
  26.     <task name="开灯" taskid="1"/>  
  27.     <task name="加速" taskid="2"/>  
  28.   </Node>  
  29.   <Node type="WorkNode" ID="6" y="327" x="637">  
  30.     <Name>充电</Name>  
  31.     <NodeTyle>收费</NodeTyle>  
  32.   </Node>  
  33.   <Node type="TaskNode" ID="7" y="327" x="301" taskNum="1">  
  34.     <Name>加亮</Name>  
  35.     <NodeTyle>收费</NodeTyle>  
  36.     <task name="调大瓦数" taskid="1"/>  
  37.   </Node>  
  38.   <Node type="WorkNode" ID="12" y="562" x="465">  
  39.     <Name>业务</Name>  
  40.     <NodeTyle>归档</NodeTyle>  
  41.   </Node>  
  42. </WorkFlow>  

下面详述XML文件的解析过程:

1.文件的读取

文件的读取使用的是Flex的FileReferenceList和FileReference类。简要叙述如下:

  1.        //代码片段1,  
  2. //其中myDrawBoard是我们自己封装的类DrawBoard的对象  
  3. //调用myDrawBoard.ParseFromXml(xml)即为调用xml解析函数  
  4. private var fr:FileReference= new FileReference();//声明FileReference对象  
  5. fr.addEventListener(Event.COMPLETE,onFileComplete);//为fr注册文件读取完毕的事件侦听函数  
  6. private function OpenFile():void//文件打开函数,程序中有其他事件响应函数调用  
  7.       {  
  8.         var fileRefList:FileReferenceList = new FileReferenceList();  
  9.         var allFilter:FileFilter = new FileFilter("xml (*.xml)""*.xml");                
  10.         if (fr.browse(new Array(allFilter))) {//调用Flex3.0的本地文件浏览对话框函数  
  11.             fr.addEventListener(Event.SELECT,onFileSelect);//注册fr的文件选取事件侦听函数  
  12.         }  
  13. }  
  14. //文件内容读取完毕,生成XML对象  
  15. private function onFileComplete(event: Event):void  
  16. {  
  17.         var xml:XML=new XML(fr.data.toString());  
  18.         this.myDrawBoard.Clear();  
  19.         this.myDrawBoard.ParseFromXml(xml);  
  20. }  
  21. private function onFileSelect(event: Event):void {  
  22.             fr.load();//文件选取完毕,载入文件内容  
  23. }  

2.xml文件的解析

xml文件的解析分有多种基本操作,现总结如下:

首先解析过程中我们会用到如下几个类:

import flash.system.ApplicationDomain;//由于解析的内容包含我自己封装的节点类的信息所以需要读取全局类域信息

XMLList类,用于实现把XML对象作为数组的方式读取,方便的进行for each操作。

这里简单的按照以下例子说明:

XML文件说明:


2.1、Load  a  XML(这部分不是我程序中使用的方法)

  1.    var xmlLoader:URLLoader = new URLLoader();  
  2. var xmlData:XML = new XML();  
  3.    
  4. xmlLoader.addEventListener(Event.COMPLETE, LoadXML);  
  5.    
  6. xmlLoader.load(new URLRequest("http://www.kirupa.com/net/files/sampleXML.xml"));  
  7.    
  8. function LoadXML(e:Event):void {  
  9. xmlData = new XML(e.target.data);  
  10. trace(xmlData);  
  11. }  
运行结果:

2.2、Access All Specified element of the XML Directly(直接遍历XML对象的所有指定子节点)

  1. function ParseBooks(bookInput:XML):void {  
  2. trace("XML Output");  
  3. trace("------------------------");  
  4. trace(bookInput.Book);  
  5. }  

输出结果如下:

XML Output
------------------------
<Book ISBN="0553212419">
  <title>Sherlock Holmes: Complete Novels and Stories, Vol 1</title>
  <author>Sir Arthur Conan Doyle</author>
</Book>
<Book ISBN="0743273567">
  <title>The Great Gatsby</title>
  <author>F. Scott Fitzgerald</author>
</Book>
<Book ISBN="0684826976">
  <title>Undaunted Courage</title>
  <author>Stephen E. Ambrose</author>
</Book>
<Book ISBN="0743203178">
  <title>Nothing Like It In the World</title>
  <author>Stephen E. Ambrose</author>
</Book>

  1.   

另外如果我们想要读取节点的某个特殊子节点,例如我们只想获得每本书的Author,可按如下操作:

  1. function ParseBooks(bookInput:XML):void {  
  2. trace("XML Output");  
  3. trace("------------------------");  
  4. trace(bookInput.Book.author);  
  5. }  

我们也可以初始化一个XMLList对象来遍历特殊子节点,代码如下:

  1. function ParseBooks(bookInput:XML):void {  
  2. trace("XML Output");  
  3. trace("------------------------");  
  4.    
  5. var authorList:XMLList = bookInput.Book.author;  
  6.    
  7. for each (var authorElement:XML in authorList) {  
  8. trace(authorElement);  
  9. }  
  10. }  


运行结果如下:
XML Output
------------------------
<author>Sir Arthur Conan Doyle</author>
<author>F. Scott Fitzgerald</author>
<author>Stephen E. Ambrose</author>
<author>Stephen E. Ambrose</author>

2.3、Access All Specified element of the XML indirectly

XMLList类对象支持许多数组对象支持的操作,另外注意到我们过滤掉XML类的子节点的返回值对象都是通过XMLList来实现的,所以我们可以用类似于遍历数组的方式来访问XML的子节点信息。

代码如下:

  1. for (var i:int = 0; i < authorList.length(); i++)  
  2. {  
  3. var authorElement:XML = authorList[i];  
  4. trace(authorElement);  
  5. }  

运行结果与上面相同。

2.3、Calling all Child (获得节点的所有子节点属性)

function ParseBooks(bookInput:XML):void {

  1. trace("XML Output");  
  2. trace("------------------------");  
  3.    
  4. var bookChildren:XMLList = bookInput.Book.children();  
  5.    
  6. for each (var bookInfo:XML in bookChildren) {  
  7. trace(bookInfo);  
  8. }  
  9. }  
运行结果如下(与之前有所不同):


XML Output
------------------------
Sherlock Holmes: Complete Novels and Stories, Vol 1
Sir Arthur Conan Doyle
The Great Gatsby
F. Scott Fitzgerald
Undaunted Courage
Stephen E. Ambrose
Nothing Like It In the World
Stephen E. Ambrose

在上述代码中我们可以通过将trace(bookinfo)改为trace(bookinfo.name)来获得节点类型,从而输出如下:

XML Output
------------------------
title
author
title
author
title
author
title
author

更复杂一点的操作:

  1. function ParseBooks(bookInput:XML):void {  
  2. trace("XML Output");  
  3. trace("------------------------");  
  4.    
  5. var bookChildren:XMLList = bookInput.Book.children();  
  6.    
  7. for each (var bookInfo:XML in bookChildren) {  
  8. if (bookInfo.name() == "author") {  
  9. trace(bookInfo);  
  10. }  
  11. }  
  12. }  

输出结果(即只输出所有author的节点的内容)。

2.4、Reading attributes(读取节点属性值)

到目前为止我们都是在处理节点(元素)以及节点的嵌套信息。节点的属性值与节点的嵌套信息不同之处在于,节点属性值直接保存在节点的内部。所以读取节点的属性值操做与处理其他节点信稍有不同。

在我们的例子XML文件中,节点的属性信息即book节点的ISBN属性的位置是直接位于book节点内部的。我们用以下AS代码来过滤book节点的ISBN信息。

  1. function ParseBooks(bookInput:XML):void {  
  2. trace("XML Output");  
  3. trace("------------------------");  
  4.    
  5. var bookAttributes:XMLList = bookInput.Book.attributes();  
  6.    
  7. for each (var bookISBN:XML in bookAttributes) {  
  8. trace(bookISBN);  
  9. }  
  10. }  

让我们把注意力集中到重点的代码上:

var bookAttributes:XMLList = bookInput.Book.attributes();

为了读取节点的属性值我们调用了attribute函数,它的返回值是一个XMLList对象,输出结果就如同我们之前调用children()函数来访问嵌套信息时输出的是真正的信息值。

有一点需要注意的是,在我们的示例XML文件中所有的node节点都只有一个属性值,在实际应用中如果一个节点有多个属性值又该怎么过滤特有的属性节点呢,有下面两种方式:

方法1:

  1. function ParseBooks(bookInput:XML):void {  
  2. trace("XML Output");  
  3. trace("------------------------");  
  4.    
  5. var bookAttributes:XMLList = bookInput.Book.attributes();  
  6.    
  7. for each (var bookISBN:XML in bookAttributes) {  
  8. if (bookISBN.name() == "ISBN") {  
  9. trace(bookISBN);  
  10. }  
  11. }  
  12. }  

方法2:

  1. function ParseBooks(bookInput:XML):void {  
  2. trace("XML Output");  
  3. trace("------------------------");  
  4.    
  5. var bookAttributes:XMLList = bookInput.Book.attribute("ISBN");  
  6.    
  7. for each (var bookISBN:XML in bookAttributes) {  
  8. trace(bookISBN);  
  9. }  
  10. }  

2.5、Filetering Node Values(过滤节点信息)

在As3中我们可以过滤出我们自己真正感兴趣的XML信息,比如我们只想找出示例XML文件中作者名是Stephen E. Ambrose 的节点信息,我们可以使用如下代码:


function ParseBooks(bookInput:XML):void {

  1. trace("XML Output");  
  2. trace("------------------------");  
  3.    
  4. var authorList:XMLList = bookInput.Book.(author == "Stephen E. Ambrose");  
  5. trace(authorList);  
  6. }  


输出结果如下:

XML Output
------------------------
<Book ISBN="0684826976">
  <title>Undaunted Courage</title>
  <author>Stephen E. Ambrose</author>
</Book>
<Book ISBN="0743203178">
  <title>Nothing Like It In the World</title>
  <author>Stephen E. Ambrose</author>
</Book>


进一步,如果我们只想提取出Stephen E. Ambrose 所写的书的Title的话,我们可以使用以下代码:


var authorList:XMLList = bookInput.Book.(author == "Stephen E. Ambrose").title;

2.6、Fuiltering Attribute Information

通过节点信息来提取特定节点数据的话只有一点不同,为了提取出一组特定ISBN的节点信息我们只需使用@操作符,具体代码如下:

  1. function ParseBooks(bookInput:XML):void {  
  2. trace("XML Output");  
  3. trace("------------------------");  
  4.    
  5. var bookList:XMLList = bookInput.Book.(@ISBN == "0743203178").title;  
  6. trace(bookList);  
  7. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值