count how many times something appears in another part of the XML document

advertisements

Let's say I have an xml file like this:

<root>
 <a><b><c> w </c></b></a>
 <x><y><z> w </z></y></x>
 <x><y><z> w </z></y></x>

and an xsl line like this:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/root">
     <xsl:value-of select="count( ./a/b[c = ./x/y/z] )"/>
  </xsl:template>
</xsl:stylesheet>

And result is 0 (I want it to be 2:)

This is just a simplified example of what I'm trying to do. Basically I want to count how many times stuff from 'a/b/c' appears in some other part of document and as you can see, I'm doing something wrong


I'm familiar with XSLT 1.0; but there's two things I see here that are off:

  • You're counting "c"'s that match some criterium; but there's only one c - you want to be counting "z"s.
  • You're evaluating ./x/y/z/ in the context of b, not in the context of root - so that xpath isn't doing what you expect.

In XSLT 1.0 (and probably without much ado in 2.0, then):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/root">
     <xsl:variable name="self" select="."/>
     <xsl:value-of select="count(x/y/z[. = $self/a/b/c] )"/>
  </xsl:template>
</xsl:stylesheet>

In your real code, it'd probably be clearer not to define a variable pointing to /root but storing the string you're looking for directly: <xsl:variable name="val" select="a/b/c"/>; either way can work.