XML в CSV с использованием пространства имен XSLT в корневом элементе - PullRequest
0 голосов
/ 27 октября 2018

Я новичок в XML и XSLT и мне нужно преобразовать XML-ответ Rest API в CSV с помощью XSLT, и мне нужен документ XSLT для подключения к программе.Я перепробовал несколько онлайн-уроков, но преобразование - это чтение всех элементов, а не только то, что мне нужно.Может кто-нибудь, пожалуйста, помогите мне!

XML ниже

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

XSLT Я пытался вывести первые 2 элемента, которые мне нужны.

<?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

EffectiveTimestamp,FromCurrency,TargetCurrency,CurrencyRateType,CurrencyRate
2018-10-26,USD,INR,CURRENT,73.865

CSV Imange

1 Ответ

0 голосов
/ 29 октября 2018

У вас проблема с этим шаблоном ....

<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: тарифа в документе, получите все zz: тарифы»

На самом деле вам не нужен 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...