首页 > 解决方案 > 如何创建全局变量以将函数的结果显示在 XSLT 中?

问题描述

关注细节以获得更好的理解。

我有这个输入示例

    <?xml version="1.0" encoding="UTF-8"?>
    <csv-xml>
       <record>
          <csv-field-1>1</csv-field-1>
          <csv-field-2>4919</csv-field-2>
          <csv-field-3>3520656</csv-field-3>
          <csv-field-4>1</csv-field-4>
          <csv-field-5>17/1/19</csv-field-5>
          <csv-field-6>17/1/19</csv-field-6>
          <csv-field-7/>
       </record>
       <record>
          <csv-field-1>2</csv-field-1>
          <csv-field-2>4919</csv-field-2>
          <csv-field-3>03451141</csv-field-3>
          <csv-field-4>1</csv-field-4>
        </record>
       <record>
          <csv-field-1>3</csv-field-1>
          <csv-field-2>4919</csv-field-2>
          <csv-field-3/>
       </record>
    </csv-xml>

这是我的代码

<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:template match="csv-xml">
        <xsl:copy>
        <xsl:apply-templates select="record[1]/csv-field-5" />         
        <xsl:value-of select=" 
           concat(format-number( number( substring-before(.,'/')), '00') , '/',
           format-number( substring-before(substring-after(.,'/'),'/'), '00'), '/',
           substring-after(substring-after(.,'/'),'/')
           )
          " />       
      </xsl:copy>    

    <xsl:variable name="header" select="record[1]" />

    <orders>
        <order  POref="{$header/csv-field-2}" accountNo="{$header/csv-field-3}" orderDate="$date1">
            <orderItems>
                <xsl:for-each select="record[position() != 1 and position() != last()]">
                    <orderItem productCode="{csv-field-3}" quantity="{csv-field-4}"/>
                </xsl:for-each>
            </orderItems>
        </order>
    </orders>
</xsl:template>
</xsl:stylesheet> 

这是我目前的输出。

    <?xml version="1.0" encoding="UTF-8"?>
    <csv-xml>17/1/19NaN/01/19
          17/1/19
          2
          4919
          03451141
          1
          3
          4919
     </csv-xml>
    <orders>
       <order POref="4919" accountNo="3520656" orderDate="$date1">
          <orderItems>
             <orderItem productCode="03451141" quantity="1"/>
          </orderItems>
       </order>
    </orders>

$date1 变量需要在 csv-field-5 的 XPath 上具有此函数的结果值

    concat(
               format-number( number( substring-before(.,'/')), '00') , '/',
               format-number( substring-before(substring-after(.,'/'),'/'), '00'), '/',
               substring-after(substring-after(.,'/'),'/')
               ) " />

我需要以上内容,因为 csv-field-5 不是 DD/MM/YY 格式。

这就是我想要达到的目标。

    </csv-xml>
    <orders>
       <order POref="4919" accountNo="3520656" orderDate="17/01/19">
          <orderItems>
             <orderItem productCode="03451141" quantity="1"/>
          </orderItems>
       </order>
    </orders>

标签: xmlxslt

解决方案


怎么样:

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:template match="/csv-xml">
    <xsl:variable name="header" select="record[1]" />
    <xsl:variable name="date" select="$header/csv-field-5" />
    <xsl:copy>
        <orders>
            <order POref="{$header/csv-field-2}" accountNo="{$header/csv-field-3}">
            <xsl:attribute name="orderDate">
                <xsl:value-of select="format-number(substring-before($date, '/'), '00')"/>  
                <xsl:text>/</xsl:text>
                <xsl:value-of select="format-number(substring-before(substring-after($date, '/'), '/'), '00')"/>  
                <xsl:text>/</xsl:text>
                <xsl:value-of select="substring-after(substring-after($date, '/'), '/')"/>  
            </xsl:attribute>
                <orderItems>
                    <xsl:for-each select="record[position() != 1 and position() != last()]">
                        <orderItem productCode="{csv-field-3}" quantity="{csv-field-4}"/>
                    </xsl:for-each>
                </orderItems>
            </order>
        </orders>
    </xsl:copy> 
</xsl:template>

</xsl:stylesheet>

如果需要,您可以将其压缩为:

<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:template match="/csv-xml">
    <xsl:variable name="header" select="record[1]" />
    <xsl:variable name="date" select="$header/csv-field-5" />
    <xsl:copy>
        <orders>
            <order  POref="{$header/csv-field-2}" 
                    accountNo="{$header/csv-field-3}" 
                    orderDate="{concat(
                        format-number(substring-before($date, '/'), '00'), '/',
                        format-number(substring-before(substring-after($date, '/'), '/'), '00'), '/', 
                        substring-after(substring-after($date, '/'), '/')
                    )}">
                <orderItems>
                    <xsl:for-each select="record[position() != 1 and position() != last()]">
                        <orderItem productCode="{csv-field-3}" quantity="{csv-field-4}"/>
                    </xsl:for-each>
                </orderItems>
            </order>
        </orders>
    </xsl:copy> 
</xsl:template>

</xsl:stylesheet>

但我更喜欢第一个版本的可读性和代码可管理性。


推荐阅读