XSL Transform, select in namespace prefix?

I am trying to select a node from the following xml that has a namespace prefix:

<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'm 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>

      

It doesn't work, the selection is empty. If I change gesmes: Envelope to simple Envelope in both xml and xsl does everything work fine?

How can I select it with a prefix?

+2


source to share


2 answers


You seem to be 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:

  • Do not use <xsl:for-each>

    whenever possible. It looks more familiar and less intimidating than it <xsl:apply-templates>

    , but it's not the best option in most cases.
  • You don't need to create elements with <xsl:element>

    , you can write them directly.
  • You don't need to store the variable with that value @time

    that interests you. You can always refer to the parent node and directly from there from it ( ../@time

    )
  • I used exclude-result-prefixes

    to make the namespace disappear from the output entirely, you seem to want to get rid of them.
+2


source


Make sure you declare the namespace at the root 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 XML input, it appears to be internal to everyone, which will never select nodes as the context changed to internal element <cube>

, namespace or not. It might just be the result of shortening your XML for the question, though ...

+3


source







All Articles