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"?>
..
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>
o;?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