4

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 query I get only item "aaa" and item "bbb".

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

However, I can kind of see why I'm not seeing item "ccc" because it is BOTH id="1" && "2"

So not really sure what the correct query should be here, and even if descendants is the correct technique.

I don't want to end up doing long additional id="1" && id="2" queries 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 one step further, how would dynamically create the @id values, because this will be a changing query depending on user selections.

Something like this (but this, but this doesn't work):

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

Any more thoughts Patrick.. anyone?

Thanks

ukmikeb
  • 303
  • 1
  • 3
  • 15
  • You should open another question since this one have been answered , an array holding your values can be made and then search into it: http://pastebin.com/vxyVK86V – Patrick May 29 '12 at 13:18

2 Answers2

1

For the Or search you can simply do :

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

Using a custom filter function you can do your And search that is more complicated than an 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"] ) ) );
Patrick
  • 15,702
  • 1
  • 39
  • 39
  • This is only returning "ccc"... This seems very useful, but am I understanding that this will ONLY return "AND" combinations. I will still need to query for "OR" separately? – ukmikeb May 28 '12 at 18:44
  • @ukmikeb Yes that was for the And search that is more complicated than the Or, i have add the Or query above. – Patrick May 28 '12 at 20:27
  • Hey Patrick you know what, your OR qury was actually EXACTLY what I needed. xml.Item.(descendants('ProductRange').(@id=="1" || @id=="2").length()>0); My OR query wasn't returning "ccc" but yours is.... many thanks! – ukmikeb May 29 '12 at 11:15
  • any thoughts on my edit above... need to make the values dynamic, from an array or string?! – ukmikeb May 29 '12 at 12:53
0

This may be messy but bear with me:

Items.Item.(
    ( descendants("ProductRange").@id == "1" || descendants("ProductRange").@id == "2" ) ||
    ( descendants("ProductRange").@id == "1" && descendants("ProductRange").@id == "2" )
)
Ahmed Nuaman
  • 12,662
  • 15
  • 55
  • 87
  • I don't think the boolean logic here is right? can you double check. How I'm reading this is if (ProductRange.id == 1 or ProductRange.id == 2) as predicate 1, this is true if either of those is true, then it's "ored" again with something that in part includes ProductRange.id==1, if that part is true the first predicate was already true, therefore "orring" it has no affect? – shaunhusain May 28 '12 at 17:47
  • Thanks for the try... but this still just returns "aaa" and "bbb". Going to try Patrick's suggestion. – ukmikeb May 28 '12 at 18:36