在根元素中使用XSLT名称空间将XML转换为CSV

时间:2018-10-27 19:36:36

标签: xml xslt

我是XML和XSLT的新手,并且需要使用XSLT将Rest API响应XML转换为CSV,并且需要XSLT文档附加到该程序。我尝试了几本在线教程,但是转换过程不仅在阅读所有元素,而且还在阅读我所需要的方式。有人可以帮我吗!

XML在下面

   {Events.map(car => (

               <tr key={car.name}>
                   <td>{car.name}</td>
                   <td>{car.timeRef}</td>
                   <td>{car.description}</td>
               </tr>
        ))}

XSLT我正在尝试输出所需的前两个元素。

    <convertTo xmlns="http://xecdapi.xe.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://xecdapi.xe.com/schema/v1/convertTo.xsd" class=" cd-browser-extension">
<terms>http://www.xe.com/legal/dfs.php</terms>
<privacy>http://www.xe.com/privacy.php</privacy>
<to>USD</to>
<amount>1.0</amount>
<timestamp>2018-10-25T00:00:00Z</timestamp>
<from>
<rate>
<currency>AUD</currency>
<mid>1.4160280983</mid>
</rate>
<rate>
<currency>SGD</currency>
<mid>1.3814918146</mid>
</rate>
<rate>
<currency>EUR</currency>
<mid>0.8773448168</mid>
</rate>
<rate>
<currency>GBP</currency>
<mid>0.7760517332</mid>
</rate>
<rate>
<currency>CAD</currency>
<mid>1.3048398838</mid>
</rate>
<rate>
<currency>INR</currency>
<mid>73.3497808743</mid>
</rate>
</from>
</convertTo>

需要CSV输出

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:zz="http://xecdapi.xe.com" version="2.0" >

 <xsl:template match="/">
          <xsl:apply-templates select="zz:convertTo"/>   
  </xsl:template>

  <xsl:template match="//zz:convertTo/zz:from/zz:rate">
     <xsl:for-each select = "//zz:convertTo/zz:from/zz:rate">
     <xsl:value-of select = "zz:currency"/>
        <xsl:value-of select="zz:mid"/>

        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

CSV Imange

1 个答案:

答案 0 :(得分:1)

您对此模板有疑问。...

<xsl:template match="//zz:convertTo/zz:from/zz:rate">
   <xsl:for-each select="//zz:convertTo/zz:from/zz:rate">
     <xsl:value-of select="zz:currency"/>
    <xsl:value-of select="zz:mid"/>
  </xsl:for-each>
</xsl:template>

首先(严格来说,在这种情况下这实际上不是问题),您不需要指定到zz:rate的完整路径。你可以做到这一点...

<xsl:template match="zz:rate">

第二次(这是一个问题),您可以在模板中执行此操作...

<xsl:for-each select="//zz:convertTo/zz:from/zz:rate">

但是,当您使用//开始表达式时,这将有效地选择XML文档中任意位置的节点,而不管您要匹配的当前节点是什么。实际上,您说的是“对于文档中的每个zz:rate,请获取所有zz:rates”

实际上,您根本不需要此xsl:for-each。您已经在与zz:rate匹配的模板中。您只需要做的就是在上一个模板中选择所需的zz:rate元素,这将停止输出诸如terms之类的节点。

尝试使用此XSLT(请注意,它缺少一个字段,因为我不确定“ CurrencyRateType”的来源

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:zz="http://xecdapi.xe.com" version="2.0" >

  <xsl:template match="/">
    <xsl:text>EffectiveTimestamp,FromCurrency,TargetCurrency,CurrencyRateType,CurrencyRate&#10;</xsl:text>
    <xsl:apply-templates select="//zz:convertTo/zz:from/zz:rate" />
  </xsl:template>

  <xsl:template match="zz:rate">
    <xsl:value-of select="substring(../../zz:timestamp, 1, 10)"/>
    <xsl:text>,</xsl:text>
    <xsl:value-of select="zz:currency"/>
    <xsl:text>,</xsl:text>
    <xsl:value-of select="../../zz:to"/>
    <xsl:text>,</xsl:text>
    <xsl:value-of select="zz:mid"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

编辑:实际上,如果您使用的是XSLT 2.0,则可以将最终模板缩短为此...

<xsl:template match="zz:rate">
  <xsl:value-of select="substring(../../zz:timestamp, 1, 10), zz:currency, ../../zz:to, zz:mid" separator=","/>
  <xsl:text>&#10;</xsl:text>
</xsl:template>