XSLT 2 |撒克逊 HE 9.5.1-2 |初始模板选择

XSLT 2 | Saxon HE 9.5.1-2 | Initial Template Selection

以下 XSLT 在 Stylus Studio 上完成了将输入无缝转换为输出的工作:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" exclude-result-prefixes="xs"/>
    <xsl:strip-space elements="*"/>
    <xsl:param name="COEP_FilePath"/>

    <xsl:template name="main>
        <xsl:element name="actualUpload" exclude-result-prefixes="xs">
            <xsl:choose>
                <xsl:when test="(not($COEP_FilePath) and not(string($COEP_FilePath)))">
                    <xsl:message terminate="yes">One or more Input Parameter(s) not supplied!</xsl:message>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:variable name="COEPData" select="unparsed-text($COEP_FilePath)"/>
                    <xsl:variable name="Tokenized_COEPData" select="tokenize($COEPData, '\r\n')"/>
                    <xsl:variable name="Period" select="normalize-space(tokenize(tokenize($COEPData, '\r\n')[1], '~')[3])"/>
                    <xsl:variable name="FiscalYear" select="normalize-space(tokenize(tokenize($COEPData, '\r\n')[1], '~')[6])"/>                    
                    <xsl:variable name="Orders" as="element(Orders)*" exclude-result-prefixes="xs">
                        <Orders>
                            <xsl:for-each select="$Tokenized_COEPData">
                                <xsl:variable name="valueInContext" select="tokenize(., '~')"/>
                                <Order>
                                    <!--<period>
                                        <xsl:value-of select="normalize-space($valueInContext[3])"/>
                                    </period>
                                    <finYear>
                                        <xsl:value-of select="normalize-space($valueInContext[6])"/>
                                    </finYear>
                                    <actualRecId>
                                        <xsl:value-of select="normalize-space($valueInContext[2])"/>
                                    </actualRecId>-->
                                    <cur>
                                        <xsl:value-of select="normalize-space($valueInContext[9])"/>
                                    </cur>
                                    <amount>
                                        <xsl:value-of select="if (ends-with(normalize-space($valueInContext[4]), '-')) then concat('-', substring-before(normalize-space($valueInContext[4]), '-')) else normalize-space($valueInContext[4])"/>
                                    </amount>
                                    <internalOrderNum>
                                        <xsl:value-of select="normalize-space($valueInContext[5])"/>
                                    </internalOrderNum>
                                </Order>
                            </xsl:for-each>
                        </Orders>
                    </xsl:variable>
                    <period>
                        <xsl:value-of select="$Period"/>
                    </period>
                    <finYear>
                        <xsl:value-of select="$FiscalYear"/>
                    </finYear>
                    <actuals>
                        <xsl:for-each-group select="$Orders/*" group-by="concat(internalOrderNum, '|', cur)">
                            <actualRec id="{internalOrderNum}">
                                <cur>
                                    <xsl:value-of select="cur"/>
                                </cur>
                                <amount>
                                    <xsl:value-of select="sum(current-group()/xs:decimal(amount))"/>
                                </amount>
                            </actualRec>    
                        </xsl:for-each-group>
                    </actuals>              
                </xsl:otherwise>
            </xsl:choose>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

为此,我必须在 Stylus Studio 的场景 Properties/Processor 部分中将初始模板值指定为 main。 XSLT 将在 java 应用程序 [使用 Saxon HE 9.5.1-2 库的 iWay 服务管理器] 中使用,我无法找出指定初始模板的方法。也许存在一个我可以利用的 JVM 选项,但我正在互联网上查找,尚未找到结果。

与此同时,我尝试解决将用户定义的模板名称 "main" 替换为 "xsl:initial-template" 的问题,以响应注意到提及此问题以进行其他 SO 讨论,没有证明是成功的。甚至在 Stylus Studio 中也不行,因为它也使用旧版本的 Saxon 库。我意识到正在使用的 Saxon HE 库需要升级到最新的维护版本。但是,这样做会对 java 应用程序产生更广泛的影响,因为我们必须对现有 solutions/etc 进行回归测试。

由于时间不够,我只想探讨以下两个选项:

1) 使用显然可以指定初始模板名称的配置文件。我虽然需要一些关于如何在 java 应用程序上启用它的建议;

2) 关于重写 XSLT 的建议,这样它就不会因为使用 unparsed-text() 函数而遇到解析错误;

关于它的价值,这是一个示例输入:

1000~1234567890~007~            12345.05-~ORDUMMYORD1        ~2019~A~04~EUR  ~          ~0212~
1000~0987654321~007~             12345.05~ORDUMMYORD1        ~2019~S~04~EUR  ~ABCDEFGHIJ~0212~
1000~6789054321~007~                  20-~ORDUMMYORD3        ~2019~A~04~EUR  ~          ~0184~

及其对应的输出:

<?xml version='1.0' encoding='UTF-8' ?>
<actualUpload>
  <period>007</period>
  <finYear>2019</finYear>
  <actuals>
    <actualRec id="ORDUMMYORD1">
      <cur>EUR</cur>
      <amount>0</amount>
    </actualRec>
    <actualRec id="ORDUMMYORD3">
      <cur>EUR</cur>
      <amount>-20</amount>
    </actualRec>
  </actuals>
</actualUpload>

求推荐。谢谢

编辑 1:13:39 CET

我已将 XSLT 修改为以下解决问题的方法:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" exclude-result-prefixes="xs"/>
    <xsl:strip-space elements="*"/>
    <xsl:param name="COEP_FilePath"/>

    <xsl:template match="/">
        <xsl:element name="actualUpload" exclude-result-prefixes="xs">
            <xsl:choose>
                <xsl:when test="(not($COEP_FilePath) and not(string($COEP_FilePath)))">
                    <xsl:message terminate="yes">One or more Input Parameter(s) not supplied!</xsl:message>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:variable name="COEPData">
                        <root>
                            <xsl:value-of select="unparsed-text($COEP_FilePath)"/>
                        </root>
                    </xsl:variable>
                    <xsl:variable name="Tokenized_COEPData" select="tokenize($COEPData/root, '\r\n')"/>
                    <xsl:variable name="Period" select="normalize-space(tokenize(tokenize($COEPData/root, '\r\n')[1], '~')[3])"/>
                    <xsl:variable name="FiscalYear" select="normalize-space(tokenize(tokenize($COEPData/root, '\r\n')[1], '~')[6])"/>
                    <xsl:variable name="Orders" as="element(Orders)*" exclude-result-prefixes="xs">
                        <Orders>
                            <xsl:for-each select="$Tokenized_COEPData">
                                <xsl:variable name="valueInContext" select="tokenize(., '~')"/>
                                <Order>
                                    <!--<period>
                                        <xsl:value-of select="normalize-space($valueInContext[3])"/>
                                    </period>
                                    <finYear>
                                        <xsl:value-of select="normalize-space($valueInContext[6])"/>
                                    </finYear>
                                    <actualRecId>
                                        <xsl:value-of select="normalize-space($valueInContext[2])"/>
                                    </actualRecId>-->
                                    <cur>
                                        <xsl:value-of select="normalize-space($valueInContext[9])"/>
                                    </cur>
                                    <amount>
                                        <xsl:value-of select="if (ends-with(normalize-space($valueInContext[4]), '-')) then concat('-', substring-before(normalize-space($valueInContext[4]), '-')) else normalize-space($valueInContext[4])"/>
                                    </amount>
                                    <internalOrderNum>
                                        <xsl:value-of select="normalize-space($valueInContext[5])"/>
                                    </internalOrderNum>
                                </Order>
                            </xsl:for-each>
                        </Orders>
                    </xsl:variable>
                    <period>
                        <xsl:value-of select="$Period"/>
                    </period>
                    <finYear>
                        <xsl:value-of select="$FiscalYear"/>
                    </finYear>
                    <actuals>
                        <xsl:for-each-group select="$Orders/*" group-by="concat(internalOrderNum, '|', cur)">
                            <actualRec id="{internalOrderNum}">
                                <cur>
                                    <xsl:value-of select="cur"/>
                                </cur>
                                <amount>
                                    <xsl:value-of select="sum(current-group()/xs:decimal(amount))"/>
                                </amount>
                            </actualRec>
                        </xsl:for-each-group>
                    </actuals>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

如果下面有评论就好了。谢谢

1) Using a configuration file where initial template name could apparently be specified. I though need some advise on how to enable this on the java application;

添加功能性 XSLT 以供参考。变量 COEPData 现在在 unparsed-text() 周围有一个 XML 标签,从而允许处理器继续操作。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" exclude-result-prefixes="xs"/>
    <xsl:strip-space elements="*"/>
    <xsl:param name="COEP_FilePath"/>

    <xsl:template match="/">
        <xsl:element name="actualUpload" exclude-result-prefixes="xs">
            <xsl:choose>
                <xsl:when test="(not($COEP_FilePath) and not(string($COEP_FilePath)))">
                    <xsl:message terminate="yes">One or more Input Parameter(s) not supplied!</xsl:message>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:variable name="COEPData">
                        <root>
                            <xsl:value-of select="unparsed-text($COEP_FilePath)"/>
                        </root>
                    </xsl:variable>
                    <xsl:variable name="Tokenized_COEPData" select="tokenize($COEPData/root, '\r\n')"/>
                    <xsl:variable name="Period" select="normalize-space(tokenize(tokenize($COEPData/root, '\r\n')[1], '~')[3])"/>
                    <xsl:variable name="FiscalYear" select="normalize-space(tokenize(tokenize($COEPData/root, '\r\n')[1], '~')[6])"/>
                    <xsl:variable name="Orders" as="element(Orders)*" exclude-result-prefixes="xs">
                        <Orders>
                            <xsl:for-each select="$Tokenized_COEPData">
                                <xsl:variable name="valueInContext" select="tokenize(., '~')"/>
                                <Order>
                                    <!--<period>
                                        <xsl:value-of select="normalize-space($valueInContext[3])"/>
                                    </period>
                                    <finYear>
                                        <xsl:value-of select="normalize-space($valueInContext[6])"/>
                                    </finYear>
                                    <actualRecId>
                                        <xsl:value-of select="normalize-space($valueInContext[2])"/>
                                    </actualRecId>-->
                                    <cur>
                                        <xsl:value-of select="normalize-space($valueInContext[9])"/>
                                    </cur>
                                    <amount>
                                        <xsl:value-of select="if (ends-with(normalize-space($valueInContext[4]), '-')) then concat('-', substring-before(normalize-space($valueInContext[4]), '-')) else normalize-space($valueInContext[4])"/>
                                    </amount>
                                    <internalOrderNum>
                                        <xsl:value-of select="normalize-space($valueInContext[5])"/>
                                    </internalOrderNum>
                                </Order>
                            </xsl:for-each>
                        </Orders>
                    </xsl:variable>
                    <period>
                        <xsl:value-of select="$Period"/>
                    </period>
                    <finYear>
                        <xsl:value-of select="$FiscalYear"/>
                    </finYear>
                    <actuals>
                        <xsl:for-each-group select="$Orders/*" group-by="concat(internalOrderNum, '|', cur)">
                            <actualRec id="{internalOrderNum}">
                                <cur>
                                    <xsl:value-of select="cur"/>
                                </cur>
                                <amount>
                                    <xsl:value-of select="sum(current-group()/xs:decimal(amount))"/>
                                </amount>
                            </actualRec>
                        </xsl:for-each-group>
                    </actuals>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>