How to match nodes that have ALL nodes in a different sequence

We are using XSLT2 . Consider if this is possible.

We have a tag filter where the customer can select all topics that match ALL of their selections.

Here is the idea of ​​the XML structure:

<themes>
   <theme>
      <name>Apple</name>
      <tags>
         <tag id="1">
         <tag id="2">
      </tags>
   </theme>
   <theme>
      <name>Banana</name>
      <tags>
         <tag id="2">
         <tag id="3">
      </tags>
   </theme>
   <theme>
      <name>Kiwifruit</name>
      <tags>
         <tag id="2">
         <tag id="3">
      </tags>
   </theme>
</themes>

      

The client selects tags 2 and 3. As a result, we want to show only the bananas and kiwis as they have all the tags that the user has selected.

We cannot use the AND operator because the tag list is long and unknown. Currently this list has moved into XSLT and then denoted:

<xsl:param name="tag_ids"/>   
<xsl:variable name="tag_id_list" select="tokenize($tag_ids,',')"/>

      

This operator selects any topic that has any of the tag_id_list:

<xsl:for-each select="themes/theme/tags/tag[@id=$tag_id_list]">

      

But we're trying to find an XPath statement that makes sure ALL s in $ tag_id_list

Any ideas ?! Thanks in advance.

+3


source to share


2 answers


This is necessary if the tags must be in the correct order:

themes/theme/tags[deep-equal($tag_id_list, tag/@id)]

      



or this if they can be in any order:

themes/theme/tags[
  (every $tag in $tag_id_list satisfies $tag = tag/@id)
    and
  (every $tag in tag/@id satisfies $tag = $tag_id_list)]

      

+4


source


You can count the number of matching tags and see if it matches the number of tags in tag_id_list

. for example

    <xsl:variable name="tagcount" select="count($tag_id_list)" />
    <xsl:for-each select="themes/theme[count(tags/tag[@id=$tag_id_list]) = $tagcount]">

      



If the customer can enter duplicate tags (eg '2,2,3'), you may need to change tagcount

to this

<xsl:variable name="tagcount" select="count(distinct-values($tag_id_list))" />

      

+1


source







All Articles