Reputation:
I'd like to select the value of a certain attribute from all tags where another attribute matches a condition.
For example, if my XML document is:
<?xml version="1.0"?>
<doc>
<mytag txt="alpha" foo="a"></mytag>
<mytag txt="beta" foo="b"></mytag>
</doc>
I'd like to use a XSLT file like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="doc/mytag">
|<xsl:value-of select="@txt[@foo='a']"/>|
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
To get output like this:
|alpha|
Instead, nothing is selected.
If I wrap the [xsl:value-of] tag with a [xsl:if test="@foo='a'"] tag, it will work:
...
<xsl:for-each select="doc/mytag">
<xsl:if test="@foo='a'">
|<xsl:value-of select="@txt"/>|
</xsl:if>
</xsl:for-each>
But I'd like to avoid that if possible, simply to save on space since I have ~20 separate tags I'd like to extract.
I'm guessing this is an xpath problem, but after fairly lengthy searching, I haven't found a solution. Any help is appreciated.
Upvotes: 1
Views: 717
Reputation: 2259
Seems like this would be better done using a template:
<transform xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
<output method="text"/>
<template match="child::doc/child::mytag[count(attribute::foo) = 1 and (string(attribute::foo) = 'a' or string(attribute::foo) = 'c')]">
<value-of select="concat('|', string(attribute::txt), '|')"/>
</template>
</transform>
Upvotes: 0
Reputation: 70598
The syntax you are looking for is this....
|<xsl:value-of select="@txt[../@foo='a']"/>|
However, this would outout ||
in the case where @foo
wasn't equal to a
. So, what you could do is more the condition to the xsl:for-each
instead
<xsl:for-each select="doc/mytag[@foo='a']">
|<xsl:value-of select="@txt"/>|
</xsl:for-each>
Upvotes: 1