如何使用xslt重构给定的xml

时间:2017-02-01 03:34:49

标签: xml xslt

我有以下xml格式。我无法将给定的输入xml完全转换为所需的输出格式。

<linked-hash-map>
  <entry>
    <string>Query</string>
    <linked-hash-map>
      <entry>
        <string>Indicator</string>
        <string>EOD</string>
      </entry>
      <entry>
        <string>End_date</string>
        <string>2016-12-25</string>
      </entry>
    </linked-hash-map>
  </entry>
  <entry>
    <string>Information</string>
    <linked-hash-map>
      <entry>
        <string>Oldest_date_available</string>
        <string>1986-03-13</string>
      </entry>
      <entry>
        <string>Newest_date_available</string>
        <string>2017-01-26</string>
      </entry>
    </linked-hash-map>
  </entry>
  <entry>
    <string>Dataset</string>
    <linked-hash-map>
      <entry>
        <string>2016-12-23</string>
        <linked-hash-map>
          <entry>
            <string>OPEN</string>
            <double>63.45</double>
          </entry>
          <entry>
            <string>Volume</string>
            <double>63.54</double>
          </entry>
        </linked-hash-map>
        </entry>
       <entry>
        <string>2016-12-22</string>
        <linked-hash-map>
          <entry>
            <string>OPEN</string>
            <double>63.84</double>
          </entry>
          <entry>
            <string>VOLUME</string>
            <double>2.21</double>
          </entry>
        </linked-hash-map>
      </entry>
    </linked-hash-map>
  </entry>
</linked-hash-map>

期望的输出:

 <linked-hash-map>
      <entry>
        <linked-hash-map>
          <Indicator>EOD</Indicator>
          <End_date>2016-12-25</End_date>
          <Oldest_date_available>1986-03-13</Oldest_date_available>
          <Newest_date_available>2017-01-26</Newest_date_available>
          <entry>
            <datarow>
            <Date>2016-12-23</Date>
            <Open>63.45</Open>
            <Volume>63.54</Volume>
            </datarow>
           <datarow>
           <Date>2016-12-22</Date>
           <Open>63.84</Open>
           <Volume>2.21</Volume>
           </datarow>
          </entry>
         </linked-hash-map>
       </entry>
     </linked-hash-map>

到目前为止,我已准备好以下XSLT。

<xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="/linked-hash-map/entry/linked-hash-map/entry">
    <xsl:choose>
      <xsl:when test="linked-hash-map">
        <datarow>
          <xsl:element name="Date">
            <xsl:value-of select="*[1]"/>
          </xsl:element>
          <xsl:for-each select="linked-hash-map/entry">
            <xsl:text disable-output-escaping="yes">&lt;</xsl:text>
            <xsl:value-of select="*[1]"/>
            <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
            <xsl:value-of select="*[2]"/>
            <xsl:text disable-output-escaping="yes">&lt;/</xsl:text>
            <xsl:value-of select="*[1]"/>
            <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
          </xsl:for-each>
        </datarow>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text disable-output-escaping="yes">&lt;</xsl:text>
        <xsl:value-of select="*[1]"/>
        <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
        <xsl:value-of select="*[2]"/>
        <xsl:text disable-output-escaping="yes">&lt;/</xsl:text>
        <xsl:value-of select="*[1]"/>
        <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template match="string"/>

对此的任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

首先,您应该从不必须通过输出转义文本来创建标记。

现在,AFAICT,所需的输出可以实现如下:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/linked-hash-map">
    <linked-hash-map>
        <entry>
            <linked-hash-map>
                <xsl:apply-templates select="entry"/>
            </linked-hash-map>
        </entry>
    </linked-hash-map>
</xsl:template>

<xsl:template match="entry">
    <xsl:apply-templates select="linked-hash-map/entry" mode="data-cell"/>
</xsl:template>

<xsl:template match="entry[string='Dataset']">
    <entry>
        <xsl:apply-templates select="linked-hash-map/entry" mode="data-row"/>
    </entry>
</xsl:template>

<xsl:template match="entry" mode="data-row">
    <datarow>
        <Date>
            <xsl:value-of select="string"/>
        </Date>
        <xsl:apply-templates select="linked-hash-map/entry" mode="data-cell"/>
    </datarow>
</xsl:template>

<xsl:template match="entry" mode="data-cell">
    <xsl:element name="{*[1]}">
        <xsl:value-of select="*[2]"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

请注意输入中<string>Volume</string><string>VOLUME</string>之间的差异;这也被带到了ouptut。