6 Replies Latest reply on Jan 6, 2010 9:47 AM by CMcM00

    What do E4X expressions return?

    CMcM00

      I'm trying to figure out XMLListCollections and E4X and since I can't find any programming reference

      I have no idea what E4X expressions do under the covers.

       

      Do they return an Object class? An XML class? An XMLList class? void?

       

      If this is my xml:

       

       

      <months>
           <month id="jan">
                .... 
           </month>
           <month id ="feb">
                ....
           </month>
      </months>
      

       

      and dataList is the XMLListCollection containing the entire XML record, then why doesn't this work?

       

      var janSubtree:XMLListCollection = new XMLListCollection(dataList.getChildAt(0).month.(@id == "jan"));
      

       

      This does work as expected:

       

      trace(dataList.getChildAt(0).month.(@id == "jan"));

       

       

      While I sure appreciate any correct answers, I would *really* appreciate someone

      explaining exactly what E4X is really doing.  I'd love to gain some insight into the gory details.

       

      Thanks for your help!!

      Cory

        • 1. Re: What do E4X expressions return?
          Flex harUI Adobe Employee

          Use toXMLString to dump the nodes at each level of the expression.  Most E4x expressions return XMLLists.  It is documented in the ASLR and in the Ecmascript spec.

           

          Alex Harui

          Flex SDK Developer

          Adobe Systems Inc.

          Blog: http://blogs.adobe.com/aharui

          • 2. Re: What do E4X expressions return?
            CMcM00 Level 1

            Hey Alex,

             

            Flex harUI wrote:

             

            Use toXMLString to dump the nodes at each level of the expression.

             

            Thanks for your reply, but I'm not following.

             

             

            This doesn't work:

             

            var janSubtree:XMLListCollection = new XMLListCollection(dataList.getChildAt(0).month.(@id == "jan").toXMLString());

             

            Nor does this:

             

            var janSubtree:XML = new XML(dataList.getChildAt(0).month.(@id == "jan").toXMLString());

             

            Nor does this:

             

            var janSubtree:XMLList = new XMLList(dataList.getChildAt(0).month.(@id == "jan").toXMLString() as XML);

             

            What am I not understanding?

             

             

            Flex harUI wrote:

            Most E4x expressions return XMLLists.  It is documented in the ASLR and in the Ecmascript spec.

             

             

            If the e4x expression is returning a XMLList, then certainly my original construction should have worked nicely, no?

             

            var janSubtree:XMLListCollection = new XMLListCollection(dataList.getChildAt(0).month.(@id == "jan"));

             

             

            Also, when I google ASLR, I get results of "Address Space Layout Randomization", a technique for randomly laying out objects in system memory to guard against hacker exploits?  Not sure how that's related to XMLListCollections or e4x...

             

            And when I take a peek at the Ecmascript for XML spec:

            http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-357.pdf

             

            I see this section on attribute identifiers:

             

            11.1.1 Attribute Identifiers
            Syntax
            
            E4X extends ECMAScript by adding attribute identifiers. 
            The syntax of an attribute identifier is specified by
            the following production:
            
                 AttributeIdentifier :
                      @PropertySelector
                      @ QualifiedIdentifier
                      @[Expression ]
                 PropertySelector :
                      Identifier
                      WildcardIdentifier
            
            Overview
            An AttributeIdentifier is used to identify the name of
            an XML attribute. It evaluates to a value of type
            AttributeName. The preceding “@” character distinguishes
            a XML attribute from a XML element with the same name. 
            This AttributeIdentifier syntax was chosen for consistency 
            with the familiar XPath syntax.
            
            Semantics
            
            The production AttributeIdentifier : @ PropertySelector 
            is evaluated as follows:
            
            1. Let name be a string value containing the same sequence
                 of characters as in the PropertySelector
            2. Return ToAttributeName(name)
            
            The production AttributeIdentifier : @ QualifiedIdentifier
            is evaluated as follows:
            1. Let q be the result of evaluating QualifiedIdentifier
            2. Return ToAttributeName(q)
            
            The production AttributeIdentifier : @ [ Expression ] is 
            evaluated as follows:
            1. Let e be the result of evaluating Expression
            2. Return ToAttributeName(GetValue(e))
            
            

             

            So I suppose that "Return ToAttributeName (GetValue(e))" means that my above e4x expressions return a String?  I have to say, I wouldn't exactly call this "documented".

             

            I have to say - on the one hand, I wonder if I'm just being an idiot for not understanding this, and on the other hand, I'm really frustrated that something that should take someone about 10-15 minutes to look up the answer to in an index is taking me at least a half a day if not more to dig through Asdoc pages, google searches, etc, with still no answer.  I do VERY much appreciate your your help, but I am more than a bit frustrated trying to figure out something that should be trivially simple - and I feel would be if the flex documentation were more complete.  Perhaps it's just late and I'm not thinking as clearly as I should be.

             

            I suppose I should stop being stubborn, and just write an actionscript function to manually do this and stop trying to filter out xml subtrees with e4x, but it seemed like it should be a very simple thing to do.

             

            Cheers,

            Cory

            • 3. Re: What do E4X expressions return?
              CMcM00 Level 1

              Ok, just thought of something...

               


              I tried doing this:

              var janSubtree:Object = dataList.getChildAt(0).month.(@id == "jan");

               

              and inspecting janSubtree in the debugger.  It's a XMLList all right. Except that inspecting the variable shows it to be empty. Which is odd since this does print the jan subtree data properly:

               

              trace(dataList.getChildAt(0).month.(@id == "jan"));

               

               

              Oh, and this doesn't work either:

              var janSubtree:XMLList = new XMLList(dataList.getChildAt(0).month.(@id == "jan"));

               

              I'm confused.

              • 4. Re: What do E4X expressions return?
                pauland Level 4

                Maybe this will help. The E4X expression returns an XMLList.

                 

                [edit: I was working on an AIR project, but you get the idea.. ]

                 

                <?xml version="1.0" encoding="utf-8"?>
                <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                                       xmlns:s="library://ns.adobe.com/flex/spark"
                                       xmlns:mx="library://ns.adobe.com/flex/halo" creationComplete="init()">
                    <fx:Declarations>
                        <!-- Place non-visual elements (e.g., services, value objects) here -->
                    </fx:Declarations>
                    <fx:Script>
                        <![CDATA[
                            import mx.collections.XMLListCollection;
                    public var dataXML:XML=<months>
                         <month id="jan">
                             jan
                         </month>
                         <month id ="feb">
                             feb
                         </month>
                    </months>;
                        public function init():void
                        {
                            var janSubtree:XMLListCollection = new XMLListCollection(dataXML.month.(@id == "jan"));
                            trace(dataXML.month.(@id == "jan"));
                        }
                           
                        ]]>
                    </fx:Script>
                </s:WindowedApplication>

                • 5. Re: What do E4X expressions return?
                  Flex harUI Adobe Employee

                  I repeat my recommendation to use toXMLString on the expressions to see what is there.  If getChildAt(0) is a month, then there is no .month in it.

                   

                  Alex Harui

                  Flex SDK Developer

                  Adobe Systems Inc.

                  Blog: http://blogs.adobe.com/aharui

                  • 6. Re: What do E4X expressions return?
                    CMcM00 Level 1

                    Hey Paul/Alex,

                     

                    Thanks so much for your help.  I figured out what was wrong. Turns out that my xml document was valid xml at the root level, but not valid xml at the month level. Therefore casting to any XML class type failed.


                    Sorry for my little whine-fest, I was a little exhausted and frustrated last night.

                     

                    In summary, using valid xml, this worked:

                     

                    var janSubtree:XMLListCollection = new XMLListCollection(dataXML.month.(@id == "jan"));

                     

                     

                    Cheers,

                    Cory