简体   繁体   English

XSL转换,选择前缀名称空间?

[英]XSL Transform, select on prefix namespace?

I am trying to select a node from the following xml that have prefix from namespace: 我正在尝试从以下具有名称空间前缀的xml中选择一个节点:

<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 我正在使用的xsl是(已更新):原始xml位于: 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? 如果我在xml和xsl上都将gesmes:Envelope更改为simple Envelope,那么一切正常吗?

How can I select it with prefix ? 如何选择带前缀的呢?

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. 查看您的逻辑和输入XML,看起来内部for-for永远不会选择节点,因为上下文已更改为内部<cube>元素,名称空间或否。 That could just be a result of shortening your XML for the question, though... 不过,这可能只是缩短您的XML的结果。

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: 应用于输入XML时,它将产生:

<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: 笔记:

  • Don't use <xsl:for-each> whenever possible. 尽可能不要使用<xsl:for-each> It looks more familiar and less frightening than <xsl:apply-templates> , but it is not the best option most of the time. <xsl:apply-templates> ,它看起来更熟悉且不那么令人恐惧,但是在大多数情况下,它并不是最佳选择。
  • You don't need to build elements with <xsl:element> , you can write them directly. 您不需要使用<xsl:element>构建元素,可以直接编写它们。
  • You don't need to store a variable with that @time value you are interested in. You can always refer to the parent node and pull it from there directly ( ../@time ) 您不需要使用您感兴趣的@time值存储变量。您始终可以引用父节点并直接从那里将其拉出( ../@time
  • I used exclude-result-prefixes to make namespaces disappear from the output entirely, you seem to want to get rid of them 我使用了exclude-result-prefixes使名称空间完全从输出中消失,您似乎想摆脱它们

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM