This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Using name() with XPath expressions (fwd)
- To: Jenny Simpson <simpson at cs dot utah dot edu>
- Subject: Re: [xsl] Using name() with XPath expressions (fwd)
- From: Jeni Tennison <mail at jenitennison dot com>
- Date: Sat, 14 Jul 2001 08:58:42 +0100
- CC: xsl-list at lists dot mulberrytech dot com
- Organization: Jeni Tennison Consulting Ltd
- References: <Pine.SGI.4.21.0107132226200.150279-100000@burn.cs.utah.edu>
- Reply-To: xsl-list at lists dot mulberrytech dot com
Hi Jenny,
> The problem is that if the variable $field contains the path of a
> text node instead of the name itself, the name function doesn't
> work. For example, if $field contains 'author/lastname', the name
> function assumes that 'author/lastname' is the string value of the
> name of a node instead of the path to a node. How do I alter this
> comparison so that it works with $field values that are paths as
> well as field values that are names? Thanks in advance.
If there are only two levels of children under bibitem, then you could
use a more general solution that used the substring before the '/' to
find the name of the child, and the substring after the '/' to find
the name of the grandchild:
<xsl:for-each select="bibliography/bibitem">
<xsl:if test="(contains($field, '/') and
$search = *[name() = substring-before($field, '/')]
/*[name() = substring-after($field, '/')]) or
$search = *[name() = $field]">
<xsl:call-template name="printBib" />
</xsl:if>
</xsl:for-each>
You can continue doing this kind of thing to an arbitrary depth, but
if you get past grandchildren you may find it simpler to create a
template that retrieves the value of the relevant descendant when
passed a path as a parameter. This template works by stepping
recursively down the path:
<xsl:template match="*" mode="string-value">
<xsl:param name="path" />
<xsl:choose>
<xsl:when test="contains($path, '/')">
<xsl:apply-templates mode="string-value"
select="*[name() = substring-before($path, '/')]">
<xsl:with-param name="path"
select="substring-after($path, '/')" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="*[name() = $path]" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
You can call this template to find the value of the node indicated by
the path, which you then test against the search string:
<xsl:for-each select="bibliography/bibitem">
<xsl:variable name="value">
<xsl:apply-templates select="." mode="string-value">
<xsl:with-param name="path" select="$field" />
</xsl:apply-templates>
</xsl:variable>
<xsl:if test="$search = $value">
<xsl:call-template name="printBib" />
</xsl:if>
</xsl:for-each>
If you reach a point where the $field parameter contains arbitrary
XPaths, including predicates and axes other than the child axis, then
you need to start thinking about using extension functions like
saxon:evaluate() to evaluate the location path, or creating XSLT using
XSLT.
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list