Today let's take a look at the new XML Processing Method in as3: E4X, until now, the ECMA scripting language specification (ECMA-262)-the core basis of ascriptscript 3.0, no XML data processing classes or methods are provided. The versions earlier than acriontscript (starting from the ActionScript in Flash 5) have some classes and methods for processing XML data, but they are not based on the ecmascript standard.
The new ECMA scripting language specification draft version 4th defines a series of new classes and methods for processing XML data. The collection of these classes and methods is named E4X ("ecmascript for XML"). ActionScript 3.0 includes the following new E4X classes: XML, xmllist, QNAME, and namespace.
The methods, attributes, and operations of the E4X class are based on the following objectives:
- Simple-E4X makes the code for processing XML data as easy as possible and easy to understand.
- Consistency-the E4X method is consistent with the other parts of ActionScript.
- Friendly-practical operators that are well understood to process XML data, such as periods (.).
Note: in order to avoid conflicts with the New XML class in E4X, the XML class in the original event 2.0 is renamed as xmldocument in event 3.0, In order to forward compatibility, the classes left over in ActionScript 3.0-XML, xmlnode, xmlparser, and xmltag-are included in flash. in the XML package. The new E4X class is the core class-you do not need to import any packages to use them.
InitializationXMLObject
An XML object can represent an XML element, attribute, comment, processing instruction, or text element. In ActionScript 3.0, we can directly assign XML data to variables:
var myXML:XML =<order><item id='1'><menuName>burger</menuName><price>3.95</price></item><item id='2'><menuName>fries</menuName><price>1.45</price></item></order>;
You can also use the new constructor to create an XML object instance from the XML data text:
var myXML:XML = new XML("<order><item id='1'><menuName>burger</menuName><price>3.95</price></item></order>");
If the XML data is not in good format (for example, the end tag is missing), a runtime error will occur.
Note: You can also import the variable instance to the XML data:
var tagname:String = "item";var attributename:String = "id";var attributevalue:String = 5;var content:String = "Chicken";var x:XML = <{tagname} {attributename}={attributevalue}>{content}</{tagname}>;trace (x.toXMLString());// Output: <item id="5">Chicken</item>
Generally, our application imports XML data from external sources, such as web service or RSS feed. The following is an example of importing XML data from a remote URL:
VaR myxml: xml = New XML (); var xml_url: String = "http://www.example.com/Sample3.xml"; // create a URLRequest. VaR myxmlurl: URLRequest = new URLRequest (xml_url); // use urlloader to import data. VaR myloader: urlloader = new urlloader (myxmlurl); // Add an event listener to post-process XML data after importing XML data. Myloader. addeventlistener ("complete", xmlloaded); // After the import is complete, create the XML Object Function xmlloaded (evtobj: Event) {var myxml: xml = XML (myloader. data); trace ("data loaded. ");}
To demonstrate the clarity of the Code, most examples in this article use 1st methods to directly create XML objects using text.
E4X contains some intuitive method XML data operators (such as. And @: used to access attributes ):
// Obtain the menuname value of the 1st items trace (myxml. item [0]. menuname); // output: burger // obtain the trace (myxml. item [0]. @ ID); // output: 1 // obtain the menuname value trace (myxml. item. (@ ID = 2 ). menuname); // output: Fries // gets the trace (myxml. item. (menuname = "burger "). price); // output: 3.95
You can also use the appendchild () method to add a new child node to XML:
var newItem:XML = <item id="3"> <menuName>medium cola</menuName> <price>1.25</price> </item>myXML.appendChild(newItem);
You can also use the @ and. Operators to update data:
AccessXMLData
You can use the. (DOT) and. operators to access the child nodes of an XML object, and use the @ operator to access the attributes of a node.
myXML.item[0].menuName="regular burger";myXML.item[1].menuName="small fries";myXML.item[2].menuName="medium cola";myXML.item.(menuName=="regular burger").@quantity = "2";myXML.item.(menuName=="small fries").@quantity = "2";myXML.item.(menuName=="medium cola").@quantity = "2";
Consider the following XML objects:
var x:XML = <order> <book ISBN="0942407296"> <title>Baking Extravagant Pastries with Kumquats</title> <author> <lastName>Contino</lastName> <firstName>Chuck</firstName> </author> <pageCount>238</pageCount> </book> <book ISBN="0865436401"> <title>Emu Care and Breeding</title> <editor> <lastName>Case</lastName> <firstName>Justin</firstName> </editor> <pageCount>115</pageCount> </book> </order>;
Object X. Book represents an xmllist object that contains all child nodes named book. The xmllist contains two XML objects (two book nodes ).
Object X. lastname indicates an xmllist object that contains all the lastname attributes in the lower part of the XML tree structure. The xmlist contains two XML objects (two lastname attributes ).
Object X. book. editor. lastname indicates the xmllist object of all lastname nodes of all the child nodes whose names are book and whose names are editor, the xmllist contains only one XML Object (the value is the lastname attribute of "case ).
Access Parent and Child Nodes
The parent () method returns the parent node of the XML object.
You can use the sequential index value of the subnode list to access specific subnodes. For example, assume that an XML Object X has two subnodes named book. You can access them as follows:
// 1st book nodes X. Book [0]; // 2nd book nodes X. Book [1];
To access the Sun Tzu node, we can use the index values of the son and Sun Tzu nodes as follows:
x.book[0].title[0];
However, if X. Book [0] has only one subnode named title, you can omit the index:
x.book[0].title;
Similarly, if the X object has only one book subnode and the subnode object of the book node has only one title object, the two index values can be omitted:
x.book.title;
Note: You can also use the child () method to directly access a specific subnode by name:
var x.XML = <order> <book> <title>Dictionary</title> </book> </order>var childName:String = "book";trace (x.child(childName).title); // Output: Dictionary
Access attributes
We use the @ operator to access the xmlnode attributes:
VaR myxml: xml = <order> <item id = '1'> <menuname> burger </menuname> <price> 3.95 </price> </item> <item id = '2'> <menuname> fries </menuname> <price> 1.45 </price> </item> </order> // obtain the trace (myxml. item [0]. @ ID); // output: 1
Filter by attribute or element valueXMLData
We can use specific element names and attribute values to locate specific elements and consider the following XML objects:
var x:XML = <employeeList> <employee id="347"> <lastName>Zmed</lastName> <firstName>Sue</firstName> <position>Data analyst</position> </employee> <employee id="348"> <lastName>McGee</lastName> <firstName>Chuck</firstName> <position>Jr. data analyst</position> </employee> </employeeList>
The following are the correct access methods:
// Lastname is the "McGee" Employee object, and the number of 1st employee nodes X. employee. (lastname = "McGee"); // The first employee node // The firstname node of the employee object whose lastname is "McGee", and the node X of the 1st employee nodes. employee. (lastname = "McGee "). firstname; // The firstname property of that node // lastname is the ID attribute of "McGee" x. employee. (lastname = "McGee "). @ ID; // The value of the ID attribute // list of all employee objects whose ID attribute value is 347 x. employee. (@ ID = 347); // lastname subnode X of the employee object whose ID attribute value is 347. employee. (@ ID = 347 ). lastname; // list of all employee objects whose ID attribute value is greater than 347 x. employee. (@ ID> 300); // an XML list with both employee properties // All position subnode values include "analyst" in the list of employee objects X. employee. (Position. tostring (). search ("analyst")>-1 );
UseFor... inAndFor each... inStatement
ActionScript 3.0 contains a new for... in statement and for each... in statement used to traverse the xmllist object. For example, consider the following XML objects: myxml and myxml... item xmllist objects (including the XML list of two item XML Object nodes ):
var myXML:XML = <order> <item id='1' quantity='2'> <menuName>burger</menuName> <price>3.95</price> </item> <item id='2' quantity='2'> <menuName>fries</menuName> <price>1.45</price> </item> </order>
The for... in statement allows us to traverse all attribute names of the xmllist, which is actually the index value of a node:
var total:Number = 0;for (var pname:String in myXML..item){ total += Number(myXML.item.@quantity[pname]) * Number(myXML.item.price[pname]);}
For each... the in statement traverses all nodes in the xmllist:
var total2:Number = 0;for each (var item:XML in myXML..item){ total2 += Number(item@quantity) * Number(item.price);}
UseWithStatement
We can use the with statement to indicate that the subsequent attributes and node values are based on an XML object. The preceding code for each... In is used as an example. The code for using the with statement is as follows:
VaR Total: Number = 0; For each (VAR item in myxml .. ITEM) {with (item) {// {the attributes and node objects are based on the item XML object.. Total + = Number (@ quantity) * Number (price) ;}} trace (total );
ModifyXMLObject
We can use the prependchild () method or the appendchild () method to add nodes to the front or back of the child node list of the XML object:
VaR X1: xml = <p> paragraph 1 </P>
VaR X2: xml = <p> paragraph 2 </P>
VaR X: xml = <body> </body>
X = x. appendchild (X1 );
X = x. appendchild (X2 );
X = x. prependchild (<p> paragraph 0 </P> );
// X = <body> <p> paragraph 0 </P> <p> paragraph 1 </P> <p> paragraph 2 </P> </body>
Use the insertchildbefore () method or the insertchildafter () method to add a node before a specific node:
VaR X: xml =
<Body>
<P> paragraph 1 </P>
<P> paragraph 2 </P>
</Body>
VaR newnode: xml = <p> paragraph 1.5 </P>
X = x. insertchildafter (X. P [0], newnode)
X = x. insertchildbefore (X. P [2], <p> paragraph 1.75 </P>)
Note: You can also use braces ({And}) to reference variables when constructing XML objects:
VaR IDs: array = [121,122,123];
VaR names: array = [["Murphy", "Pat"], ["Thibaut", "Jean"], ["Smith", "Vijay"]
VaR X: xml = New XML ("<employeelist> </employeelist> ");
For (var I: Int = 0; I <3; I ++ ){
VaR newnode: xml = New XML ();
Newnode =
<Employee ID = {IDs [I]}>
<Last> {Names [I] [0]} </last>
<First> {Names [I] [1]} </first>
</Employee>
X = x. appendchild (newnode)
}
We can also use the = Operator to assign values to XML Object nodes:
VaR X: xml =
<Employee>
<Lastname> Smith </lastname>
</Employee>
X. firstname = "Jean ";
X. @ ID = "239 ";
The code above sets XML Object X to the following:
<Employee ID = "239">
<Lastname> Smith </lastname>
<Firstname> Jean </firstname>
</Employee>
We can also use the + and + = operators to link xmllist:
VaR X1: xml = <A> test1 </a>
VaR X2: xml = <B> Test2 </B>
VaR xlist: xmllist = X1 + x2;
Xlist + = <C> test3 </C>
DeleteXMLObject
The Delete and deletebyindex methods are defined in the E4X specifications to delete specific XML nodes. However, the two methods are not implemented in the implementation of the current version of ActionScript 3.0, we cannot directly use these two methods. However, we can traverse the XML tree, remove specific nodes, and reconstruct the New XML Object method to delete a specific node, we will delete the lastname subnode of the employee as follows:
Private function deletebyindex (xmlnode: XML, index: Number): XML {
VaR newstr: String = '';
Newstr + = '<' + xmlnode. localname ();
For each (VAR Att: XML in xmlnode. attributes ()){
Newstr + = ''+ Att. localname () + '="' + Att. tostring () + '"';
}
Newstr + = '> ';
VaR I: Number = 0;
For each (VAR node: XML in xmlnode. Children ()){
If (I! = Index)
Newstr + = node. toxmlstring ();
I ++;
}
Newstr + = '</' + xmlnode. localname () + '/> ';
Return New XML (newstr );
}
VaR myxml: xml =
<Employee ID = "239">
<Lastname> Smith </lastname>
<Firstname> Jean </firstname>
<Address>
<City> Shangrao </city>
<Load> daihu </load>
<NO> 5 </NO>
</Address>
</Employee>
Myxml = deletebyindex (myxml, 0 );
The preceding deletebyindex function has two parameters: 1st is the parent node of the deleted node, and 2nd is the index value of the deleted node in the subnode list of the parent node. Traverse the index attributes of the parent node, traverse all its child nodes, skip the nodes we want to delete, and then combine them into a new XML object to return.
If the XML object is very complex and the data volume is large, the efficiency of the method for deleting nodes is very low. The correct choice is to use the deletion method defined by E4X, however, this function will not be available until the next beta version of ActionScript 3.0.
XMLType conversion
We can convert XML objects and xmllist objects to strings. Similarly, we can also convert strings to XML objects and xmllist objects. By the way, remember that all XML property values, names, and text values are strings.
ConversionXMLAndXmllistThe object is a string
Both the XML object and the xmllist object have two member Methods: tostring () and toxmlstring. The toxmlstring () method returns a string that contains all tags, attributes, namespace declarations, and XML Object content. It corresponds to complex XML objects (including child elements), and tostring () the effect of the method is the same as that of the toxmlstring () method. However, for a simple XML Object (containing only one text element), The tostring () method only returns the text content of the element:
VaR myxml: xml =
<Order>
<Item id = '1' quantity = '2'>
<Menuname> burger </menuname>
<Price> 3.95 </price>
</Item>
<Order>
Trace (myxml. item0.menuname. toxmlstring ())
// Output: <menuname> burger </menuname>
Trace (myxml. item0.menuname. tostring ())
// Output: burger
Convert a text string to an XML Object
We can use the new constructor to create an XML object from a string.
VaR X: xml = New XML ('<A> test <B> ');
However, if we try to convert a non-XML string or an incomplete structure to an XML object, a runtime error will be reported:
VaR X: xml = New XML ('<A> test'); // throws an error
SlaveInternetReadRSS FEADData
The following code reads the rss fead data on this site:
<? XML version = "1.0" encoding = "UTF-8"?>
<Mx: Application xmlns: MX = "http://www.macromedia.com/2005/mxml" xmlns = "*" creationcomplete = "doinit ()">
<Mx: SCRIPT>
<! [CDATA [
Private function doinit (): void {
Getrssdata ("http://blog.eshangrao.com/rss.php", ta_view );
}
Public Function getrssdata (URL: String, outtxt: textarea): void
{
Private var myxmlurl: URLRequest = new URLRequest (URL );
Private var myloader: urlloader = new urlloader (myxmlurl );
Myloader. addeventlistener ("complete", xmlloaded );
}
Private function xmlloaded (Event: Event): void {
Ta_view.text = 'Load OK ';
VaR myloader: urlloader = urlloader(event.tar get );
XML. ignoreprocessinginstructions = false;
VaR myxml: xml = New XML (myloader. data );
Private var outstr: String = "";
For each (VAR item: XML in myxml. Children ()){
If (item. localname () = 'item '){
Outstr + = "<p> <B>" + item. Children () 0. tostring () + ": </B> </P> <p> ";
Outstr + = item. Children () 6. tostring ();
Outstr + = "<br/> <a href = '" + item. Children () 1. tostring ();
Outstr + = "'> <font color =' #008000 '> more... </font> </a> </P> ";
}
}
// Ta_view.text = myxml. tostring ();
Ta_view.htmltext = outstr;
}
]>
</MX: SCRIPT>
<Mx: canvas width = "100%" Height = "100%">
<Mx: textarea id = "ta_view">
<Mx: layoutconstraints>
<Mx: edgeanchor Bottom = "10" Top = "10" Left = "10" Right = "10"/>
</MX: layoutconstraints>
</MX: textarea>
</MX: canvas>
</MX: Application>
Running example (flashplayer8.5 required)
Note: We did not directly use the node name to access the node (I don't know why, if you use item. when the title node is accessed by the title node, the returned result is null, which may be related to the RDF instruction in my rss xml. If a friend knows the solution, please let me know ), instead, the children () method is used to return all the child node objects of an XML object.