xsl-list
[Top] [All Lists]

[xsl] Getting Unexpected Results from .//* = $set-of-elements

2018-02-23 17:10:10
I'm implementing a filtering process where I want to filter out everything 
except the ancestors of specified elements (user provides a list of IDs to 
keep), as well as specific subelements of the ancestors (e.g., header elements 
within HTML sections).

I'm using Saxon PE 9.7.0.19 (as included with Oxygen 19.1) and and XSLT 2 
template. The source doc is XHTML:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"; > .. </html>

At the start of my processing I create a variable that is the list of elements 
to keep:

    <xsl:variable name="elements-to-keep" as="element()*"
      select="
      for $id in $element-ids-for-filtering
      return key('elementsById', $id, .)
      "
    />

I've verified that this produces the expected list of elements.

I then filter like so, here in the context of a template that handles html 
section elements:


  <xsl:template mode="filter-by-element-id" match="xhtml:section | xhtml:div" 
priority="10">
    <xsl:param name="elements-to-keep" as="element()*" tunnel="yes"/>

    <xsl:choose>
      <xsl:when test=". = $elements-to-keep">
        <xsl:next-match/>
      </xsl:when>
      <xsl:when test=".//* = $elements-to-keep">
        <xsl:copy>
          <xsl:apply-templates mode="#current" select="@*, *"/>
        </xsl:copy>
      </xsl:when>
      <xsl:otherwise>
          <xsl:message>+ [DEBUG] filter-by-element-id:   Section does not 
contain any elements to keep, ignoring it.</xsl:message>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

What I think I'm saying is:

IF current element is in $elements-to-keep, keep it (next match copies it to 
output)
IF any descendant of current element is in $elements-to-keep, process the 
current element
Otherwise ignore the element.

In my test data I have this figure element:

<figure id="x88B6B95AEAD3
 <img id="x88B6B95AEADC" />  
</figure>

If I specify the ID of the figure, the result is as expected--I get the figure 
and all of the ancestor sections and nothing else.

However, if I specify the ID of the img element, I get not only the section I 
want but other sections, because the second <when> in the choice above resolves 
as true() when it should not.

Through experimentation I determined that the variable is whether or not the 
element with the ID is an empty element or not.

If the element is not empty, I get the correct behavior. 

If the element is empty, I get the incorrect behavior.

Why would I be getting this behavior? 

Could this be a Saxon bug or is there some subtlety in the "=" operator that 
I'm missing?

What's particularly odd is that I'm getting a false positive from elements that 
do not have the element in $elements-to-keep as a descendant.

Thanks,

Eliot
--
Eliot Kimber
http://contrext.com
 
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>