Reputation: 141
I have a xml and I want the attribute which is defined in the "title" using XSL file. I want to retrieve the value of style both "abc" and "cdf" values
<catalog>
<cd>
<title style="abc:true;cdf:false" att2="false">Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>
i tried this
<td><xsl:value-of select="substring-before(substring-after(@style,'abc:'),';')"/></td>
Upvotes: 2
Views: 2212
Reputation: 243479
This is a generic transformation that allows a string containing indefinite number of name-value pairs to be processed:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:variable name="vStyle" select="/*/*/title/@style"/>
The value for 'abc' is : <xsl:text/>
<xsl:call-template name="getValueOfName">
<xsl:with-param name="pText" select="$vStyle"/>
<xsl:with-param name="pName" select="'abc'"/>
</xsl:call-template>
The value for 'cdf' is : <xsl:text/>
<xsl:call-template name="getValueOfName">
<xsl:with-param name="pText" select="$vStyle"/>
<xsl:with-param name="pName" select="'cdf'"/>
</xsl:call-template>
The value for 'xyz' is : <xsl:text/>
<xsl:call-template name="getValueOfName">
<xsl:with-param name="pText" select="$vStyle"/>
<xsl:with-param name="pName" select="'xyz'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="getValueOfName">
<xsl:param name="pText"/>
<xsl:param name="pName"/>
<xsl:choose>
<xsl:when test="not(string-length($pText) > 0)"
>***Not Found***</xsl:when>
<xsl:otherwise>
<xsl:variable name="vPair" select=
"substring-before(concat($pText, ';'), ';')"/>
<xsl:choose>
<xsl:when test=
"$pName = substring-before(concat($vPair, ':'), ':')">
<xsl:value-of select="substring-after($vPair, ':')"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="getValueOfName">
<xsl:with-param name="pText" select=
"substring-after($pText, ';')"/>
<xsl:with-param name="pName" select="$pName"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<catalog>
<cd>
<title style="abc:true;cdf:false" att2="false">Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>
produces the wanted result:
The value for 'abc' is : true
The value for 'cdf' is : false
The value for 'xyz' is : ***Not Found***
Explanation:
The getValueOfName
template is a generic template that finds the name-value pair containing the specified pName
and then outputs the value -- or if this name isn't found at all, the string ***Not Found***
is output.
The template first gets the first name-value pair from the string and processes it. In case the pName
isn't present in the current name-value pair, then the template calls itself recursively on the text following the current name-value-pair.
Upvotes: 3
Reputation: 9048
I suspect your problem relates to the way you are referencing the @style attribute.
If you are using XPath 2.0, you can use a function call (e.g. substring-after, substring-before) to the right of the / operator. So this will work:
/catalog/cd/title/substring-before(substring-after(@style,'abc:'),';')
In XPath 1.0, you cannot do this, the thing to the right of each / must be an axis step (not a function call), so you would have to use:
substring-before(substring-after(/catalog/cd/title/@style,'abc:'),';')
Upvotes: 2
Reputation: 42453
I think you're close:
<!-- abc -->
<xsl:value-of
select="substring-after(
substring-before(/catalog/cd/title/@style,';'),'abc:')"/>
<!-- cdf -->
<xsl:value-of
select="substring-after(
substring-after(/catalog/cd/title/@style,';'),'cdf:')"/>
Upvotes: 1