Question

<?xml version="1.0" encoding="utf-8"?>
<transaction>
    <itemset id="1">
        <item>pen</item>
        <item>notebook</item>
        <item>pencile box</item>
    </itemset>
<itemset id="2">
    <item>pen</item>
    <item>notebook</item>
    <item>pencile box</item>
    <item>ink</item>
</itemset>
<itemset id="3">
    <item>ink</item>
    <item>milk</item>
</itemset>
<itemset id="4">
    <item>pen</item>
    <item>notebook</item>
    <item>pencile box</item>
    <item>ink</item>
    <item>milk</item>
    <item>paper</item>
</itemset>
<itemset id="5">
    <item>pen</item>
    <item>ink</item>
    <item>notebook</item>
</itemset>
</transaction>

Suppose I have a list of distinct items. I want to search each item from an itemset. If the itemset have that item, then I will return that itemset with all items. For example, I have a distinct list of items (milk,paper (this is not fixed---dynamic list)). Milk is in itemset-3 and itemset-4, So I will add itemset-3 and itemset-4 in a new XML list, then paper is in itemset 4 only. But itemset-4 is already in the list so no need to add the itemset 4 again. My question is how do I get an itemset using XQuery based on each item and the itemset is added only once in my new list. I am using BaseX to run XQuery command.

Expected output looks like

    <?xml version="1.0" encoding="utf-8"?>
<transaction>
<itemset id="3">
    <item>ink</item>
    <item>milk</item>
</itemset>
<itemset id="4">
    <item>pen</item>
    <item>notebook</item>
    <item>pencile box</item>
    <item>ink</item>
    <item>milk</item>
    <item>paper</item>
</itemset>
</transaction>

The code I have tried:

let $src:= doc('XML/test_my.xml')/transaction
let $allitems := $src/itemset/item
let $C:=distinct-values($allitems)
for $value in $C
    let $def:=$src/itemset[item=$value]
    return $def

But it return itemset repeatedly for two or more distinct items. How do I stop to print the existing itemset? Please help me...

Était-ce utile?

La solution

The mistake in your code is that you search for each (distinct) value separately. As suggested by Phil, you should do a combined search for all values in one XPath. If you drop the for line, and replace the let $def with an expression that searches all values, you'll be there. Something like:

let $allitems := $src/itemset/item
let $C:=distinct-values($allitems)
let $def:=$src/itemset[item=$C]
return $def

You can replace $C here by any sequence of values, for instance:

let $C := ('milk', 'paper')

The = operator is capable of comparing sequences and node-sets, effectively doing an intersect. It returns true if the intersect isn't empty.

HTH!

Autres conseils

Something like this

/transaction/itemset[item='milk' or item='paper']

Demo here - http://www.xpathtester.com/obj/01c525c6-14ae-427b-b6c6-26f8e1ef17a7

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top