2010-07-26 3 views
2

Existe-t-il une XMLList équivalente à Array.indexOf?savoir si XMLList AS3 contient une chaîne comme valeur de nœud

Par exemple -

var array:Array = ['one','two']; 
trace(array.indexOf('two')); // returns 1, since it's at the second position 
trace(array.indexOf('three')); // returns -1, since it isn't found 

... droite? mais si je l'ai eu ce -

var xml:XML = <list><item>one</item><item>two</item><list> 
var xmlList:XMLList = list.item; 

il faut que ce soit un moyen plus facile de vérifier si l'un des nœuds du XMLList a une valeur particulière que boucle par tous, non? quelque chose de semblable à -

xmlList.indexOfChildByNodeValue('two'); // returns 1, because it's the second child 
xmlList.indexOfChildByNodeValue('three'); // returns -1, because it doesn't match any children 

avez-vous un sens?

Répondre

5

J'ai mis en place une démo de comment vous pouvez le faire sans boucle. Bien que cela demande un peu plus de travail en amont. Bien que cela rapporte si vous allez vérifier les valeurs beaucoup.

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
       xmlns:s="library://ns.adobe.com/flex/spark" 
       xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" applicationComplete="_init();"> 
    <fx:Declarations> 
     <fx:XML id="movieList" source="http://www.movies.com/rss-feeds/jen-yamato-reviews-rss" /> 
    </fx:Declarations> 
    <fx:Script> 
     <![CDATA[ 
      import mx.logging.ILogger; 
      import mx.logging.Log; 
      import mx.logging.LogEventLevel; 
      import mx.logging.targets.TraceTarget; 

      public static const MOVIE_TITLE:String = "Inception"; 

      private var _logger:ILogger = Log.getLogger("Sandbox"); 

      private function _init() :void 
      { 
       var traceTarget:TraceTarget = new TraceTarget(); 
       traceTarget.level = LogEventLevel.ALL; 
       Log.addTarget(traceTarget); 

       var xmlList:XMLList = movieList..item; 

       var firstItem:XML = movieList..item[0]; 
       var firstItemIndex:int = firstItem.childIndex(); 
       _logger.info("First Item Index: " + firstItemIndex); 

       var item:XML = xmlList.(title == MOVIE_TITLE)[0]; 
       _logger.info("Contains: " + xmlList.contains(item) + " // " + item.childIndex()); 

       var actualIndex:int = (item.childIndex() - firstItemIndex); 
       _logger.info("Actual Index: " + actualIndex); 

       _logger.info("Result: " + xmlList[actualIndex]); 
      } 
     ]]> 
    </fx:Script> 

</s:Application> 

L'idée de base est que vous stockez l'index du premier item puis soustrayez que de la childIndex() du résultat apparié en utilisant la recherche E4X.

+0

Wow, overachiever! Je me suis dit qu'il y avait une façon cool de le faire avec E4X - donc la viande de votre exemple est "movieList..item." (Title == 'MovieTitle') "pas vrai? Cela fonctionne parce que chaque noeud d'élément a un noeud de titre - dans mon cas, imaginez que les noeuds d'élément ne contiennent rien mais les titres de film comme valeur de noeud. cela finirait-il par ressembler à ... "movieList .. (item == 'MovieTitle')"? –

+1

Dans votre exemple ce sera: xmlList. (ToString() == "un") – Patrick

+0

@ matt-lohkamp - haha, merci. J'aime vérifier que ma réponse est correcte dans un bac à sable avant de l'afficher ici. Patrick a raison de le faire en utilisant votre exemple. Personnellement, j'utiliserais 'text()' plutôt que 'toString()'. Consultez la documentation et décidez par vous-même des meilleures suites pour vos besoins. http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/XML.html – cynicaljoy

1

Je pense que le seul pari est de faire une boucle sur le XMLList. L'autre option que vous avez est d'utiliser: contains() Bien que cela aidera seulement dans votre situation si vous voulez seulement savoir si indexOf() == || != -1. Je ne suis pas sûr de la façon dont le XMLList est réellement stocké dans le C++ sous-jacent, mais s'il s'agit vraiment d'un tableau, alors une recherche linéaire O (n) est le meilleur que vous ferez.

+0

Je suis sûr qu'une recherche linéaire est ce qui se passe essentiellement sous le capot pour Array.indexOf, alors oui, vous avez probablement raison. Je voulais juste m'assurer qu'il n'y avait pas une façon plus facile d'écrire cette ligne de code. J'ai regardé XMLList.contains(), mais cela correspond à des nœuds XML, et dans cette situation, je ne connais que la valeur du texte du nœud (qui est XML.toString()), pas la valeur des autres attributs - Je devine cette fonction veut une correspondance exacte, pas seulement une correspondance sur la valeur du noeud. merci! –

Questions connexes