E4X select nodes where descendants can be either A OR B or A && B

So, I have this XML structure:

<Items> <Item name="aaa"> <ProductRanges> <ProductRange id="1" /> </ProductRanges> </Item> <Item name="bbb"> <ProductRanges> <ProductRange id="2" /> </ProductRanges> </Item> <Item name="ccc"> <ProductRanges> <ProductRange id="1" /> <ProductRange id="2" /> </ProductRanges> </Item> </Items> 

Using the following E4X request, I get only the "aaa" element and the "bbb" element.

 trace( Items.Item.(descendants("ProductRange") .@id == "1" || descendants("ProductRange") .@id == "2") ); 

However, I can see why I do not see the ccc element because it is BOTH id = "1" && & "2"

So I’m not quite sure what the correct request should be here, and even if the descendants are the right technique.

I don’t want to end up doing a long extra id = "1" && & & id = "2" either because I have unlimited combinations of these values ​​("2" & "3", "1" & "2" & "3"), etc.

Any thoughts would be most helpful.

thanks


So Patrick solved this with this expression:

 xml.Item.(descendants('ProductRange').(@id=="1" || @id=="2").length()>0); 

However, taking this step further, it would be like dynamically creating @id values, because this will be a changing query depending on user selections.

Something like this (but this, but this does not work):

 var attributeValues:String = "@id==\"1\" || @id==\"2\" || @id==\"3\" || @id==\"4\""; xml.Item.(descendants('ProductRange').(attributeValues).length()>0); 

Any thoughts on Patrick .. anyone?

thanks

+4
source share
2 answers

To search Or you can just do:

 xml.Item.(descendants('ProductRange').(@id=="1" || @id=="2").length()>0); 

Using a custom filter function, you can search and search more complex than Or:

 var xml:XML=<Items> <Item name="aaa"> <ProductRanges> <ProductRange id="1" /> </ProductRanges> </Item> <Item name="bbb"> <ProductRanges> <ProductRange id="2" /> </ProductRanges> </Item> <Item name="ccc"> <ProductRanges> <ProductRange id="1" /> <ProductRange id="3" /> <ProductRange id="2" /> </ProductRanges> </Item> </Items>; function andSearch(node:XMLList, searchFor:Array) { var mask:int = 0; var match:int = (1 << searchFor.length ) - 1; var fn:Function = function(id:String) { var i:int = searchFor.indexOf(id); if (i >= 0) { mask = mask | (1<<i); } return mask==match; } node.(ProductRange.(fn(@id))); return mask==match; } trace( xml.Item.( andSearch( ProductRanges, ["1", "2"] ) ) ); 
+1
source

It may be dirty, but carry with me:

 Items.Item.( ( descendants("ProductRange") .@id == "1" || descendants("ProductRange") .@id == "2" ) || ( descendants("ProductRange") .@id == "1" && descendants("ProductRange") .@id == "2" ) ) 
0
source

Source: https://habr.com/ru/post/1414742/


All Articles