通过 DataGrid 操作 XML 文件,增加(最后一个)记录、删除记录。
难点:增加记录和删除记录时必须直接对 XML 操作,datagrid.selectedIndex 和 xml.childIndex 均失效,需要借助添加一个 XML 属性值 index 来标记。
AIR 运行效果如下:
XML 数据文件 test.xml 内容效果如下:
1 <?xml version="1.0" encoding="utf-8"?>
2 <data>
3 <stock index="0">
4 <symbol>600066</symbol>
5 <title>宇通客车</title>
6 </stock>
7 <stock index="2">
8 <symbol>000002</symbol>
9 <title>万科</title>
10 </stock>
11 <stock index="3">
12 <symbol>000825</symbol>
13 <title>太钢不锈</title>
14 </stock>
15 </data>
2 <data>
3 <stock index="0">
4 <symbol>600066</symbol>
5 <title>宇通客车</title>
6 </stock>
7 <stock index="2">
8 <symbol>000002</symbol>
9 <title>万科</title>
10 </stock>
11 <stock index="3">
12 <symbol>000825</symbol>
13 <title>太钢不锈</title>
14 </stock>
15 </data>
FileTest.mxml 内容如下:
1 <?xml version="1.0" encoding="utf-8"?>
2 <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
3 xmlns:s="library://ns.adobe.com/flex/spark"
4 xmlns:mx="library://ns.adobe.com/flex/mx"
5 >
6
7 <fx:Declarations>
8 <!-- 将非可视元素(例如服务、值对象)放在此处 -->
9 </fx:Declarations>
10
11 <fx:Script>
12 <![CDATA[
13 import mx.controls.*;
14 import mx.events.ListEvent;
15
16 import nonamecat.finance.vo.Stock;
17
18 var loaded:Boolean = false;
19 var file:File = File.documentsDirectory;
20
21 var xml:XML = <data></data>;
22
23
24 protected function btnRead_clickHandler(event:MouseEvent):void
25 {
26 this.selectOpenFile(this.file);
27 }
28
29 // 打开文件选择窗口,用于读取 XML
30 protected function selectOpenFile(root:File):void
31 {
32 var txtFilter:FileFilter = new FileFilter("Xml File", "*.xml");
33 root.browseForOpen("Open", [txtFilter]);
34 root.addEventListener(Event.SELECT, fileOpenSelected);
35 }
36
37 // 打开文件选择窗口,用于保存 XML
38 protected function selectSaveFile(root:File):void
39 {
40 var txtFilter:FileFilter = new FileFilter("Xml File", "*.xml");
41 root.browseForOpen("Open", [txtFilter]);
42 root.addEventListener(Event.SELECT, fileSaveSelected);
43 }
44
45 // 当用于读取 XML 的文件被选中时触发的事件
46 protected function fileOpenSelected(event:Event):void
47 {
48 this.fileOpen();
49 }
50
51 // 当用于保存 XML 的文件被选中时触发的事件
52 protected function fileSaveSelected(event:Event):void
53 {
54 this.fileSave();
55 }
56
57 // 从文件读取 XML
58 protected function fileOpen():void
59 {
60 trace(this.file.nativePath);
61 var stream:FileStream = new FileStream();
62 stream.open(this.file, FileMode.READ);
63 this.xml = XML(stream.readUTFBytes(stream.bytesAvailable));
64 stream.close();
65 this.loaded = true;
66
67 dgBox.dataProvider=this.xml.children();
68
69 // 临时 debug 信息
70 this.txtBox.text = this.xml.toXMLString();
71 }
72
73 // 把 XML 直接写入文件
74 protected function fileSave():void
75 {
76
77 var outputString:String = '<?xml version="1.0" encoding="utf-8"?>\n';
78 outputString += this.xml.toXMLString();
79
80 outputString = outputString.replace(/\n/g, File.lineEnding);
81 outputString = outputString.replace(/></g, ">"+File.lineEnding+"<");
82
83 var stream:FileStream = new FileStream();
84 stream = new FileStream();
85 stream.open(this.file, FileMode.WRITE);
86 stream.writeUTFBytes(outputString);
87 stream.close();
88 this.loaded = true;
89
90 // 临时 debug 信息
91 this.txtBox.text = outputString;
92 }
93
94 // 触发写入文件的事件
95 // 如果不曾打开或者保存过,则让用户选择要保存的文件
96 // 如果已经打开或者保存过,则直接保存
97 protected function btnWrite_clickHandler(event:MouseEvent):void
98 {
99 if(!this.loaded){
100 this.selectSaveFile(this.file);
101 }else{
102 fileSave();
103 }
104
105 }
106
107
108 // 向 DataGrid 添加一行
109 // 在没有记录的时候,自动添加一个空白记录,并使 index 属性値为 0
110 // 在有记录的时候,寻找最后一个记录,取得 index 属性値,并令其加一,成为新的空白记录的 index 属性値
111 protected function btnNew_clickHandler(event:MouseEvent):void
112 {
113 var lastIndex:uint;
114 if(this.xml.stock.length() == 0){
115 lastIndex=0;
116 }else{
117 lastIndex = this.xml.stock[this.xml.stock.length()-1].@index;
118 lastIndex++;
119 }
120 var node:XML = <stock index={lastIndex}><symbol></symbol><title></title></stock>;
121 this.xml.appendChild(node);
122 this.dgBox.dataProvider=this.xml.children();
123
124
125 }
126
127 // 从 DataGrid 移除一行
128 // 由于 DataGrid 数据源是 XML,所以直接操作 XML
129 // 从 XML 移除具有所选节点的 index 属性的所有记录
130 protected function btnRemove_clickHandler(event:MouseEvent):void
131 {
132 var node:XML = this.dgBox.selectedItem as XML;
133 this.txtBox.text = node;
134 var i:String = node.index;
135
136 delete this.xml.stock.(@index==node.@index)[0];
137 this.dgBox.dataProvider=this.xml.children();
138 }
139
140
141 ]]>
142 </fx:Script>
143
144
145 <s:Button x="226" y="289" label="读取" click="btnRead_clickHandler(event)" id="btnRead" enabled="true"/>
146 <s:RichEditableText x="83" y="50" width="115" height="260" id="txtBox" enabled="true"/>
147 <s:Button x="395" y="289" label="写入" id="btnWrite" enabled="true" click="btnWrite_clickHandler(event)"/>
148 <mx:DataGrid x="221" y="52" id="dgBox" editable="true" selectable="true" width="243">
149 <mx:columns>
150 <mx:DataGridColumn headerText=" " editable="false"/>
151 <mx:DataGridColumn headerText="symbol" dataField="symbol"/>
152 <mx:DataGridColumn headerText="title" dataField="title"/>
153 </mx:columns>
154 </mx:DataGrid>
155 <s:Button x="225" y="231" label="添加" id="btnNew" enabled="true" click="btnNew_clickHandler(event)"/>
156 <s:Button x="395" y="231" label="移除" id="btnRemove" enabled="true" click="btnRemove_clickHandler(event)"/>
157 </s:WindowedApplication>
158
2 <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
3 xmlns:s="library://ns.adobe.com/flex/spark"
4 xmlns:mx="library://ns.adobe.com/flex/mx"
5 >
6
7 <fx:Declarations>
8 <!-- 将非可视元素(例如服务、值对象)放在此处 -->
9 </fx:Declarations>
10
11 <fx:Script>
12 <![CDATA[
13 import mx.controls.*;
14 import mx.events.ListEvent;
15
16 import nonamecat.finance.vo.Stock;
17
18 var loaded:Boolean = false;
19 var file:File = File.documentsDirectory;
20
21 var xml:XML = <data></data>;
22
23
24 protected function btnRead_clickHandler(event:MouseEvent):void
25 {
26 this.selectOpenFile(this.file);
27 }
28
29 // 打开文件选择窗口,用于读取 XML
30 protected function selectOpenFile(root:File):void
31 {
32 var txtFilter:FileFilter = new FileFilter("Xml File", "*.xml");
33 root.browseForOpen("Open", [txtFilter]);
34 root.addEventListener(Event.SELECT, fileOpenSelected);
35 }
36
37 // 打开文件选择窗口,用于保存 XML
38 protected function selectSaveFile(root:File):void
39 {
40 var txtFilter:FileFilter = new FileFilter("Xml File", "*.xml");
41 root.browseForOpen("Open", [txtFilter]);
42 root.addEventListener(Event.SELECT, fileSaveSelected);
43 }
44
45 // 当用于读取 XML 的文件被选中时触发的事件
46 protected function fileOpenSelected(event:Event):void
47 {
48 this.fileOpen();
49 }
50
51 // 当用于保存 XML 的文件被选中时触发的事件
52 protected function fileSaveSelected(event:Event):void
53 {
54 this.fileSave();
55 }
56
57 // 从文件读取 XML
58 protected function fileOpen():void
59 {
60 trace(this.file.nativePath);
61 var stream:FileStream = new FileStream();
62 stream.open(this.file, FileMode.READ);
63 this.xml = XML(stream.readUTFBytes(stream.bytesAvailable));
64 stream.close();
65 this.loaded = true;
66
67 dgBox.dataProvider=this.xml.children();
68
69 // 临时 debug 信息
70 this.txtBox.text = this.xml.toXMLString();
71 }
72
73 // 把 XML 直接写入文件
74 protected function fileSave():void
75 {
76
77 var outputString:String = '<?xml version="1.0" encoding="utf-8"?>\n';
78 outputString += this.xml.toXMLString();
79
80 outputString = outputString.replace(/\n/g, File.lineEnding);
81 outputString = outputString.replace(/></g, ">"+File.lineEnding+"<");
82
83 var stream:FileStream = new FileStream();
84 stream = new FileStream();
85 stream.open(this.file, FileMode.WRITE);
86 stream.writeUTFBytes(outputString);
87 stream.close();
88 this.loaded = true;
89
90 // 临时 debug 信息
91 this.txtBox.text = outputString;
92 }
93
94 // 触发写入文件的事件
95 // 如果不曾打开或者保存过,则让用户选择要保存的文件
96 // 如果已经打开或者保存过,则直接保存
97 protected function btnWrite_clickHandler(event:MouseEvent):void
98 {
99 if(!this.loaded){
100 this.selectSaveFile(this.file);
101 }else{
102 fileSave();
103 }
104
105 }
106
107
108 // 向 DataGrid 添加一行
109 // 在没有记录的时候,自动添加一个空白记录,并使 index 属性値为 0
110 // 在有记录的时候,寻找最后一个记录,取得 index 属性値,并令其加一,成为新的空白记录的 index 属性値
111 protected function btnNew_clickHandler(event:MouseEvent):void
112 {
113 var lastIndex:uint;
114 if(this.xml.stock.length() == 0){
115 lastIndex=0;
116 }else{
117 lastIndex = this.xml.stock[this.xml.stock.length()-1].@index;
118 lastIndex++;
119 }
120 var node:XML = <stock index={lastIndex}><symbol></symbol><title></title></stock>;
121 this.xml.appendChild(node);
122 this.dgBox.dataProvider=this.xml.children();
123
124
125 }
126
127 // 从 DataGrid 移除一行
128 // 由于 DataGrid 数据源是 XML,所以直接操作 XML
129 // 从 XML 移除具有所选节点的 index 属性的所有记录
130 protected function btnRemove_clickHandler(event:MouseEvent):void
131 {
132 var node:XML = this.dgBox.selectedItem as XML;
133 this.txtBox.text = node;
134 var i:String = node.index;
135
136 delete this.xml.stock.(@index==node.@index)[0];
137 this.dgBox.dataProvider=this.xml.children();
138 }
139
140
141 ]]>
142 </fx:Script>
143
144
145 <s:Button x="226" y="289" label="读取" click="btnRead_clickHandler(event)" id="btnRead" enabled="true"/>
146 <s:RichEditableText x="83" y="50" width="115" height="260" id="txtBox" enabled="true"/>
147 <s:Button x="395" y="289" label="写入" id="btnWrite" enabled="true" click="btnWrite_clickHandler(event)"/>
148 <mx:DataGrid x="221" y="52" id="dgBox" editable="true" selectable="true" width="243">
149 <mx:columns>
150 <mx:DataGridColumn headerText=" " editable="false"/>
151 <mx:DataGridColumn headerText="symbol" dataField="symbol"/>
152 <mx:DataGridColumn headerText="title" dataField="title"/>
153 </mx:columns>
154 </mx:DataGrid>
155 <s:Button x="225" y="231" label="添加" id="btnNew" enabled="true" click="btnNew_clickHandler(event)"/>
156 <s:Button x="395" y="231" label="移除" id="btnRemove" enabled="true" click="btnRemove_clickHandler(event)"/>
157 </s:WindowedApplication>
158