I've got an XSLT template which counts topics at all levels, for use in labeling those topics with numbering in DITA projects I've got.
<xsl:template match="*[contains(@class, ' bookmap/chapter ')] | *[contains(@class, ' map/topicref ')] [not(ancestor-or-self::*[contains(@class,' bookmap/frontmatter ')])]" mode="topicTitleNumber">
<xsl:number format="1 " count="*[contains(@class, ' map/topicref ')] [not(ancestor-or-self::*[contains(@class,' bookmap/frontmatter ')])] | *[contains(@class, ' bookmap/chapter ')]" level="multiple"/>
</xsl:template>
I'm trying to add an additional exclusion to what gets counted though, for when a topicref
class has a title
element with an outputclass
of noNum
.
<xsl:template match="*[contains(@class, ' bookmap/chapter ')] | *[contains(@class, ' map/topicref ')] [not(ancestor-or-self::*[contains(@class,' bookmap/frontmatter ')])]" mode="topicTitleNumber">
<xsl:number format="1 " count="*[contains(@class, ' map/topicref ')] [not(ancestor-or-self::*[contains(@class,' bookmap/frontmatter ')] | *[contains(title/@outputclass, 'noNum')])] | *[contains(@class, ' bookmap/chapter ')]" level="multiple"/>
</xsl:template>
Shown above, I added | *[contains(title/@outputclass, 'noNum')]
after the first not
statement, thinking that would function as an additional condition in which the count
call would skip over when the template was called (i.e. ...not an ancestor-or-self with [criteria] or a topic with title outputclass attribute of 'noNum'...). However it appears that the criteria I added is treated as something the template does match on and count.
Assuming that I am correct on the last point, I believe I need to put that condition inside of its own 'not' statement, but I'm not sure how to do that with the conditions already present in the XPath.
In XPath |
is a set union operator, not a logical OR.
|
The
|
operator computes the union of its operands, which must be node-sets.
The
union
and|
operators are equivalent. They take two node sequences as operands and return a sequence containing all the nodes that occur in either of the operands.
or
Use or
instead for logical OR .
Break it down to smaller parts:
Does //*[contains(@class, ' bookmap/chapter ')]
select what you expect? Repeat for each of the most basic parts of your logical expression individually.
Combine those individually verified terms or predicates, one at a time, and observe that each step along the way, there are not surprises.
Repair any discrepancies between expected and actual results before combining additional terms.