如何使用xslt添加根元素?

时间:2019-05-14 09:43:33

标签: xslt

我有一个XML文件,我只想保留以下标记:

assetId, index, basis1, rate, spread, pors, matDate, notional, currNotional, fixingDate and intDays

以下是原始XML文件的示例:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
  <messageDetail>
    <transaction>
      <trades>
        <trade>
          <tradeInfoString>SPOT_FX</tradeInfoString>
          <tradeStatusCode>AMENDED</tradeStatusCode>
          <enteredDateTime>2019-05-09T10:49:05+01:00</enteredDateTime>
          <reference>3956502P</reference>
          <version>4</version>
          <tradeDate>2016-06-24</tradeDate>
          <tradeTypeCode>MARKET</tradeTypeCode>
          <tradeLegs>
            <tradeLeg>
              <bookId>721</bookId>
              <assetId>001FM1C9</assetId>
              <index>FIXED</index>
              <basis1>30/360</basis1>
              <rate>-0.381</rate>
              <spread>0</spread>
              <pors>Sale</pors>
              <matDate>2019-05-09</matDate>
              <notional>0.00</notional>
              <currNotional>25000000.00</currNotional>
              <transfers>
                <transfer>
                  <transferType>INTEREST</transferType>
                  <longShort>LONG</longShort>
                  <amount>82285.42</amount>
                  <settlementDate>2017-05-09</settlementDate>
                  <fixingDate>9999-12-31</fixingDate>
                  <intDays>311</intDays>
                  <instrument>
                    <type>CURRENCY</type>
                    <currency>EUR</currency>
                  </instrument>
                </transfer>
                <transfer>
                  <transferType>INTEREST</transferType>
                  <longShort>LONG</longShort>
                  <amount>95250.00</amount>
                  <settlementDate>2018-05-09</settlementDate>
                  <fixingDate>9999-12-31</fixingDate>
                  <intDays>360</intDays>
                  <instrument>
                    <type>CURRENCY</type>
                    <currency>EUR</currency>
                  </instrument>
                </transfer>
              </transfers>
            </tradeLeg>
            <tradeLeg>
              <bookId>721</bookId>
              <assetId>001FM1CB</assetId>
              <index>FORM</index>
              <basis1>A360</basis1>
              <rate>0</rate>
              <spread>0</spread>
              <pors>Purchase</pors>
              <matDate>2019-05-09</matDate>
              <notional>0.00</notional>
              <currNotional>25000000.00</currNotional>
              <transfers>
                <transfer>
                  <transferType>INTEREST</transferType>
                  <longShort>SHORT</longShort>
                  <amount>10150.00</amount>
                  <settlementDate>2016-08-09</settlementDate>
                  <fixingDate>2016-06-24</fixingDate>
                  <intDays>42</intDays>
                  <instrument>
                    <type>CURRENCY</type>
                    <currency>EUR</currency>
                  </instrument>
                </transfer>
              </transfers>
            </tradeLeg>
          </tradeLegs>
          <endDate>2019-05-09</endDate>
          <startDate>2016-06-28</startDate>
          <systemProductCode>SWAP</systemProductCode>
        </trade>
      </trades>
    </transaction>
  </messageDetail>

为此,我使用了以下XSLT文件:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:hsbcfixml="http://www.fixprotocol.org/FIXML-4-4"
    exclude-result-prefixes="hsbcfixml">
    <xsl:output method="xml" encoding="UTF-8" 
        indent="yes" />

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template
        match="node()[not(self::tradeLeg or ancestor-or-self::assetId or ancestor-or-self::index or ancestor-or-self::basis1 or ancestor-or-self::rate or ancestor-or-self::spread or ancestor-or-self::pors or ancestor-or-self::matDate or ancestor-or-self::notional or ancestor-or-self::currNotional or ancestor-or-self::fixingDate or ancestor-or-self::intDays)]">
        <xsl:apply-templates />
    </xsl:template>
</xsl:stylesheet>

产生了以下输出:

<tradeLeg>
   <assetId>001FM1C9</assetId>
   <index>FIXED</index>
   <basis1>30/360</basis1>
   <rate>-0.381</rate>
   <spread>0</spread>
   <pors>Sale</pors>
   <matDate>2019-05-09</matDate>
   <notional>0.00</notional>
   <currNotional>25000000.00</currNotional>
   <fixingDate>9999-12-31</fixingDate>
   <intDays>311</intDays>
   <fixingDate>9999-12-31</fixingDate>
   <intDays>360</intDays>
</tradeLeg>
<tradeLeg>
   <assetId>001FM1CB</assetId>
   <index>FORM</index>
   <basis1>A360</basis1>
   <rate>0</rate>
   <spread>0</spread>
   <pors>Purchase</pors>
   <matDate>2019-05-09</matDate>
   <notional>0.00</notional>
   <currNotional>25000000.00</currNotional>
   <fixingDate>2016-06-24</fixingDate>
   <intDays>42</intDays>
</tradeLeg>

问题在于输出不是有效的XML文件,缺少XML声明和根元素(XML验证抱怨The markup in the document following the root element must be well-formed.

如何更改XSLT以解决此问题?

1 个答案:

答案 0 :(得分:1)

要匹配xslt中的根节点,可以使用'/'。

它选择根节点,该根节点是包含所有其他节点的文档节点。

此代码可以帮助实现相同目的:

<xsl:template match="/">
    <root>
        <xsl:apply-templates />
    </root>
</xsl:template>

您可以按如下所示修改xslt以添加根元素。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:hsbcfixml="http://www.fixprotocol.org/FIXML-4-4"
exclude-result-prefixes="hsbcfixml">

<xsl:output method="xml" encoding="UTF-8" indent="yes" />

<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
</xsl:template>

<xsl:template match="/">
    <root>
        <xsl:apply-templates />
    </root>
</xsl:template>

<xsl:template
    match="node()[not(self::tradeLeg or ancestor-or-self::assetId or ancestor-or-self::index or ancestor-or-self::basis1 or ancestor-or-self::rate or ancestor-or-self::spread or ancestor-or-self::pors or ancestor-or-self::matDate or ancestor-or-self::notional or ancestor-or-self::currNotional or ancestor-or-self::fixingDate or ancestor-or-self::intDays)]">
    <xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>

在此处查看演示:https://xsltfiddle.liberty-development.net/bnnZWv

让我知道我是否想念一些东西。