9 Replies Latest reply on Feb 12, 2007 12:09 PM by MarkuzAddiktuz

    e4x predicate filtering bug???

    MarkuzAddiktuz
      Hi guys! I'm having problems searching a very simple xml file. Here is my mxml code:

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="vertical" xmlns:ns1="view.*" initialize="initApp()">
      <mx:Script>
      <![CDATA[
      import mx.controls.Alert;
      private var xml:XML = <reviews>
      <review>
      <tags>
      <tag>tag four</tag>
      <tag>tag three</tag>
      <tag>tag one</tag>
      </tags>
      </review>
      <review>
      <tags>
      <tag>tag three</tag>
      <tag>tag five</tag>
      <tag>tag one</tag>
      </tags>
      </review>
      <review>
      <tags>
      <tag>tag three</tag>
      </tags>
      </review>
      <review>
      <tags>
      <tag>tag one</tag>
      <tag>tag two</tag>
      <tag>tag three</tag>
      <tag>tag five</tag>
      </tags>
      </review>
      <review>
      <tags>
      <tag>tag one</tag>
      </tags>
      </review>
      </reviews>

      private function initApp():void{
      var x:XML = new XML(xml);
      mx.controls.Alert.show(x);
      var xmlList:XMLList = x..review.tags.(tag == "tag one") as XMLList;
      mx.controls.Alert.show("xmlList length is: " + xmlList.length());
      }

      ]]>
      </mx:Script>
      </mx:Application>

      ----

      Shouldn't the xmlList length return 4 since there are 4 (tags) nodes that contain a "tag one" tag? Anyone having the same issue? am i doing something wrong?

      Thanks in advance...
        • 1. Re: e4x predicate filtering bug???
          Dzihan
          Hi Markuz,

          var x:XML = new XML(xml);
          what's this for?

          var xmlList:XMLList = x..review.tags.(tag == "tag one") as XMLList;
          you don't need ".." before review, "." does the job because all review nodes are on first level of the rootNode
          (you only need ".." if you have more review nodes inside the review nodes on level1)

          I'm not sure but i think in AS3 its xmlList.length; and not xmlList.length();

          I would try

          var xmlList:XMLList = x.review.tags.(tag == "tag one");
          trace(xmlList.toXMLString());

          or

          var xmlList:XMLList = x..tags.(tag == "tag one");
          trace(xmlList.toXMLString());

          Good Luck ! :)



          • 2. Re: e4x predicate filtering bug???
            FlightGuy Level 1
            You should get 4 nodes from your query as far as I can see - you don't tell us what you do get.

            Tim
            • 3. Re: e4x predicate filtering bug???
              MarkuzAddiktuz Level 1
              Hi dzihan,

              Thanks for the reply. The line:

              var x:XML = new XML(xml);

              is not needed. It was part of a legacy code. The line:

              xml..review.tags.(tag=="tag one") as XMLList;

              (specifically ".." is actually needed. check the XML structure: <review> nodes within <reviews> node)

              Here is the code without the unnecessary codes:

              <?xml version="1.0" encoding="utf-8"?>
              <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="vertical" xmlns:ns1="view.*" initialize="initApp()">
              <mx:Script>
              <![CDATA[
              import mx.controls.Alert;
              private var xml:XML = <reviews>
              <review>
              <tags>
              <tag>tag four</tag>
              <tag>tag three</tag>
              <tag>tag one</tag>
              </tags>
              </review>
              <review>
              <tags>
              <tag>tag three</tag>
              <tag>tag five</tag>
              <tag>tag one</tag>
              </tags>
              </review>
              <review>
              <tags>
              <tag>tag three</tag>
              </tags>
              </review>
              <review>
              <tags>
              <tag>tag one</tag>
              <tag>tag two</tag>
              <tag>tag three</tag>
              <tag>tag five</tag>
              </tags>
              </review>
              <review>
              <tags>
              <tag>tag one</tag>
              </tags>
              </review>
              </reviews>
              private function initApp():void{
              var xmlList:XMLList = xml..review.tags.(tag=="tag one") as XMLList;
              mx.controls.Alert.show(xmlList);
              }
              ]]>
              </mx:Script>
              </mx:Application>


              The thing is, the syntax:

              xml..review.tags.(tag=="tag one") as XMLList

              is indeed able to search a tag node containing the value "tag one". The problem is that it's not finding them all. it only finds one when it should find four. (check the XML) Any ideas on this? Could this be a bug?
              • 4. Re: e4x predicate filtering bug???
                FlightGuy Level 1
                In fact for the XML you have you don't need the .. - the top level <reviews> is represented by the variable "xml", so if you were to reference xml.review it would return all the reviews in your sample XML.

                Do you get all of them if you remove the predicate? If you just do xml..review.tags, or if you do xml.review.tags?

                Do you get a list of the right tags if you do xml..review.tags.tag?

                Tim
                • 5. Re: e4x predicate filtering bug???
                  MarkuzAddiktuz Level 1
                  Hi!

                  Thanks guys.. what i'm trying to do is get an xmllist that has "tag one" in its tags.. try copying and pasting my code.. the xmllist is returning one <review></review> node instead of four..

                  the interesting thing is this - if you use regular expressions, you get the expected results:

                  replace:

                  xml..review.tags.(tag=="tag one") as XMLList

                  with

                  xml..review.tags.(/tag one/.test(tag)) as XMLList;

                  This looks like a bug to me. Go ahead and copy and paste the code so you can see it for yourselves.

                  Thanks...
                  • 6. Re: e4x predicate filtering bug???
                    FlightGuy Level 1
                    OK, I copied and pasted it and I get the same behavior. The one that it is selecting is the one that only has a <tag>tag one</tag> - if you try modifying one of the other reviews to have only one <tag> node that is "tag one", it picks that up too. It seems to be doing a short-circuit evaluation and excluding the node when one of its children fails the test.

                    After a bit more analysis I've realized what's happening. The tag variable in the predicate is not a string - it's an XMLList. In the simplest case, where there is only one tag by that name, it returns a node with a simple string in it. In the more complex case where there are multiple children, it returns an XMLList with all the children. This is why your regexp works.

                    Try this:
                    var xmlList:XMLList = xml.review.tags.(isOne(tag)) as XMLList;

                    and then
                    private function isOne(t:*):Boolean{
                    trace(t);
                    return (t == "tag one");
                    }

                    Tim
                    • 7. Re: e4x predicate filtering bug???
                      FlightGuy Level 1
                      I know it's not the solution - but it explains the observed behavior.
                      • 8. Re: e4x predicate filtering bug???
                        FlightGuy Level 1
                        OK, try this:
                        var xmlList:XMLList = xml.review.tags.(tag.contains(<tag>tag one</tag>)) as XMLList;

                        Tim
                        • 9. Re: e4x predicate filtering bug???
                          MarkuzAddiktuz Level 1
                          kool.. thanks man.. i owe you one.. :-)