Why does this XQuery filter return unwanted elements?

Viewed 83

I'm using BaseX 8.4.1 which implements XQuery 3.1

I'm trying to do a quite basic thing in XQuery, but I cannot seem to figure it out.

I created some example data that illustrates what I am trying to do. My data set looks like this. It is a simple embedded structure. There are days, each day has some events, and events have members.

Data

<root>
    <day>
        <name>1</name>
        <event>
            <name>1</name>
            <member>A</member>
            <member>B</member>
        </event>
        <event>
            <name>2</name>
            <member>C</member>
        </event>
    </day>
    <day>
        <name>2</name>
        <event>
            <name>3</name>
            <member>A</member>
            <member>B</member>
        </event>
        <event>
            <name>4</name>
            <member>C</member>
        </event>
    </day>
    <day>
        <name>3</name>
        <event>
            <name>5</name>
            <member>C</member>
        </event>
    </day>
</root>

What I want to do, is get a list of members, and for each member get a list of days on which they have events, and the events they have. So the result should look like this:

Desired Results

<member>
  <name>A</name>
  <day>
    <name>1</name>
    <event>
      <name>1</name>
      <member>A</member>
      <member>B</member>
    </event>
  </day>
  <day>
    <name>2</name>
    <event>
      <name>3</name>
      <member>A</member>
      <member>B</member>
    </event>
  </day>
</member>
<member>
  <name>B</name>
  <day>
    <name>1</name>
    <event>
      <name>1</name>
      <member>A</member>
      <member>B</member>
    </event>
  </day>
  <day>
    <name>2</name>
    <event>
      <name>3</name>
      <member>A</member>
      <member>B</member>
    </event>
  </day>
</member>
<member>
  <name>C</name>
  <day>
    <name>1</name>
    <event>
      <name>2</name>
      <member>C</member>
    </event>
  </day>
  <day>
    <name>2</name>
    <event>
      <name>4</name>
      <member>C</member>
    </event>
  </day>
  <day>
    <name>3</name>
    <event>
      <name>5</name>
      <member>C</member>
    </event>
  </day>
</member>

To accomplish this, I tried the following XQuery:

What I tried

for $member in distinct-values(//member)
return
<member>
  <name>{$member}</name>
    {for $day in //day where $day/event/member = $member
      let $event := $day/event where $event/member = $member
    return 
      <day>
        {$day/name}
        {$event}
    </day>}
</member>

However, this does not apply the filtering. So I keep all the events for a member that they are not a member of:

What I got

<member>
  <name>A</name>
  <day>
    <name>1</name>
    <event>
      <name>1</name>
      <member>A</member>
      <member>B</member>
    </event>
    <event>
      <name>2</name>
      <member>C</member>
    </event>
  </day>
  <day>
    <name>2</name>
    <event>
      <name>3</name>
      <member>A</member>
      <member>B</member>
    </event>
    <event>
      <name>4</name>
      <member>C</member>
    </event>
  </day>
</member>
<member>
  <name>B</name>
  <day>
    <name>1</name>
    <event>
      <name>1</name>
      <member>A</member>
      <member>B</member>
    </event>
    <event>
      <name>2</name>
      <member>C</member>
    </event>
  </day>
  <day>
    <name>2</name>
    <event>
      <name>3</name>
      <member>A</member>
      <member>B</member>
    </event>
    <event>
      <name>4</name>
      <member>C</member>
    </event>
  </day>
</member>
<member>
  <name>C</name>
  <day>
    <name>1</name>
    <event>
      <name>1</name>
      <member>A</member>
      <member>B</member>
    </event>
    <event>
      <name>2</name>
      <member>C</member>
    </event>
  </day>
  <day>
    <name>2</name>
    <event>
      <name>3</name>
      <member>A</member>
      <member>B</member>
    </event>
    <event>
      <name>4</name>
      <member>C</member>
    </event>
  </day>
  <day>
    <name>3</name>
    <event>
      <name>5</name>
      <member>C</member>
    </event>
  </day>
</member>

Surely, this should be quite easy, no?

2 Answers
Related