pi-attribute

pi-attribute — Extract a pseudo-attribute from a PI

Description

The pi-attribute template extracts a pseudo-attribute from a processing instruction. For example, given the PI <?foo bar="1" baz='red'?>,

<xsl:call-template name="pi-attribute">
  <xsl:with-param name="pis" select="processing-instruction('foo')"/>
  <xsl:with-param name="attribute" select="'baz'"/>
</xsl:call-template>

will return red. This template returns the first matching attribute that it finds. Presented with processing instructions that contain badly formed pseudo-attributes (missing or unbalanced quotes, for example), the template may silently return erroneous results.

<xsl:template name="pi-attribute">
  <xsl:param name="pis" select="processing-instruction('BOGUS_PI')"></xsl:param>
  <xsl:param name="attribute">filename</xsl:param>
  <xsl:param name="count">1</xsl:param>

  <xsl:choose>
    <xsl:when test="$count>count($pis)">
      <!-- not found -->
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="pi">
        <xsl:value-of select="$pis[$count]"></xsl:value-of>
      </xsl:variable>
      <xsl:variable name="pivalue">
        <xsl:value-of select="concat(' ', normalize-space($pi))"></xsl:value-of>
      </xsl:variable>
      <xsl:choose>
        <xsl:when test="contains($pivalue,concat(' ', $attribute, '='))">
          <xsl:variable name="rest" select="substring-after($pivalue,concat(' ', $attribute,'='))"></xsl:variable>
          <xsl:variable name="quote" select="substring($rest,1,1)"></xsl:variable>
          <xsl:value-of select="substring-before(substring($rest,2),$quote)"></xsl:value-of>
        </xsl:when>
        <xsl:otherwise>
          <xsl:call-template name="pi-attribute">
            <xsl:with-param name="pis" select="$pis"></xsl:with-param>
            <xsl:with-param name="attribute" select="$attribute"></xsl:with-param>
            <xsl:with-param name="count" select="$count + 1"></xsl:with-param>
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>