[xsl] Immediate uncle

Subject: [xsl] Immediate uncle
From: "Trevor Nicholls" <trevor@xxxxxxxxxxxxxxxxxx>
Date: Tue, 6 Sep 2005 00:33:22 +1200
Hi

I have some XML which contains references to several types of images, and
one type in particular is defined in the following form:

------
<XML>
 ...
 <DIV>
  <IMAGE href="gif">
 </DIV>
 <Figure>Image caption</Figure>
 ...
</XML>
------

I am trying to refactor this XML so that for this kind of image the caption
becomes one of the attributes of the image, like so:

------
...
<screenshot source="gif" caption="Image caption" />
...
------

The stylesheet which I am using initially did something like this (ignoring
the caption for the moment):

------
<!-- IMAGE within its own DIV is a screenshot, otherwise an inline img -->
<xsl:template match="IMAGE">
  <xsl:choose>
    <xsl:when test="name(..)='DIV'">
      <screenshot>
        <xsl:attribute name="source">
          <xsl:value-of select="@href"/>
        </xsl:attribute>
      </screenshot>
    </xsl:when>
    <xsl:otherwise>
      <img>
        <xsl:attribute name="source">
          <xsl:value-of select="@href"/>
        </xsl:attribute>
      </img>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
------

To get the caption in there requires me to access the content of the first
following uncle of the context (IMAGE) node, provided that this uncle is a
"Figure".

I thought I could do this by making the following adjustment to the
<screenshot> section of the IMAGE template:

------
  <screenshot>
    <xsl:attribute name="source">
      <xsl:value-of select="@href"/>
    </xsl:attribute>
<!-- If a (DIV/IMAGE, Figure) combination then we have a caption -->
    <xsl:if test="..[following-sibling::*[1]][self::Figure]">
      <xsl:attribute name="caption">
        <xsl:value-of select="..[following-sibling::*[1]]" />
      </xsl:attribute>
    </xsl:if>
  </screenshot>
------

This fails, however, as the test is an invalid expression. I know that
  <xsl:if test="child::*[1][self::Figure]">
is valid because I use something equivalent to it elsewhere; thus I presume
that
  <xsl:if test=" following-sibling::*[1][self::Figure]">
would also be valid. So I presume the problem lies in trying to use that
entire expression as a predicate of the parent node? Is there a (better) way
to do what I am trying to do?

Thank you
Trevor

Current Thread