Reputation: 45
I am trying to select a node from the following xml that have prefix from namespace:
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01">
<Cube>
<Cube time="2009-10-12">
<Cube currency="USD" rate="1.4765"/>
.............................
the xsl I am using is (Updated): The original xml is at: http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xdoc>
<ccurency>
<xsl:for-each select="gesmes:Envelope/Cube/Cube">
<xsl:variable name="atime" select="@time"/>
<xsl:for-each select="Cube">
<row>
<xsl:element name="Date">
<xsl:value-of select="$atime"/>
</xsl:element>
<xsl:element name="Currency">
<xsl:value-of select="@currency"/>
</xsl:element>
<xsl:element name="Rate">
<xsl:value-of select="@rate"/>
</xsl:element>
</row>
</xsl:for-each>
</xsl:for-each>
</ccurency>
</xdoc>
</xsl:template>
</xsl:stylesheet>
This is not working, the select is empty. If I change the gesmes:Envelope to simple Envelope both at xml and xsl everything works fine?
How can I select it with prefix ?
Upvotes: 2
Views: 5540
Reputation: 338208
It seems that you are looking for something like this:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"
xmlns:exr="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
exclude-result-prefixes="gesmes exr"
>
<xsl:output method="xml" indent="yes" encoding="utf-8" />
<xsl:template match="gesmes:Envelope">
<xdoc>
<ccurency>
<xsl:apply-templates select="exr:Cube/exr:Cube/exr:Cube" />
</ccurency>
</xdoc>
</xsl:template>
<xsl:template match="exr:Cube[@currency and @rate]">
<row>
<Date>
<xsl:value-of select="../@time" />
</Date>
<Currency>
<xsl:value-of select="@currency" />
</Currency>
<Rate>
<xsl:value-of select="@rate" />
</Rate>
</row>
</xsl:template>
</xsl:stylesheet>
When applied to your input XML, it produces:
<xdoc>
<ccurency>
<row>
<Date>2009-07-16</Date>
<Currency>PHP</Currency>
<Rate>67.739</Rate>
</row>
<row>
<Date>2009-07-16</Date>
<Currency>SGD</Currency>
<Rate>2.0501</Rate>
</row>
<row>
<Date>2009-07-16</Date>
<Currency>THB</Currency>
<Rate>48.13</Rate>
</row>
<row>
<Date>2009-07-16</Date>
<Currency>ZAR</Currency>
<Rate>11.4575</Rate>
</row>
</ccurency>
</xdoc>
Notes:
<xsl:for-each>
whenever possible. It looks more familiar and less frightening than <xsl:apply-templates>
, but it is not the best option most of the time.<xsl:element>
, you can write them directly.@time
value you are interested in. You can always refer to the parent node and pull it from there directly (../@time
)exclude-result-prefixes
to make namespaces disappear from the output entirely, you seem to want to get rid of themUpvotes: 2
Reputation: 32447
Make sure that you've declared the namespace in the root element of the transform:
<xsl:stylesheet xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
Looking at your logic and input XML, it looks like the inner for-each will never select nodes, since the context is changed to the inner <cube>
element, namespace or no. That could just be a result of shortening your XML for the question, though...
Upvotes: 3