当前位置: 首页 > 知识库问答 >
问题:

XSLT 2|Saxon HE 9.5.1-2|初始模板选择

侯善
2023-03-14

以下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的场景属性/处理器部分指定要使用的初始模板值。XSLT将用于java应用程序[使用Saxon HE 9.5.1-2库的iWay Service Manager],我无法找出指定初始模板的方法。也许我可以利用一个JVM选项,但我正在Internet上查找,还没有点击。

与此同时,我试图解决将用户定义的模板名称“main”替换为“xsl:initial template”的问题,以回应在其他SO讨论中提到这一点的通知,但没有成功。即使在Stylus Studio中也不行,因为它也使用了旧版本的Saxon lib。我意识到使用中的Saxon HE库需要升级到最新的维护版本。然而,这样做将对java应用程序产生更广泛的影响,因为我们必须对现有解决方案进行回归测试。

由于时间有限,我只想探讨以下两个选择:

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)使用可以指定初始模板名称的配置文件。我需要一些关于如何在java应用程序上启用此功能的建议;

共有1个答案

通学真
2023-03-14

添加功能XSLT以供参考。变量COEPData现在有一个围绕未解析文本()的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>
 类似资料:
  • 我认为模板函数可以有默认的参数参数(不是模板参数而是运行时参数)。我们也可以用空括号初始化来初始化一个类。但是编译器如何匹配模板呢? 这段代码为什么要编译,编译器如何进行演绎,以及这个函数调用示例中的参数是什么? 我所理解的是:默认括号初始化调用空构造函数,这是隐式创建的,因为没有用户定义的构造函数或用户定义的默认构造函数。也就是说,我们可以用{}初始化任何包。所以扣除不适用于那里,因为我们不能选

  • 本文向大家介绍Angular 2 初始化,包括了Angular 2 初始化的使用技巧和注意事项,需要的朋友参考一下 示例 组件或指令属性已初始化时触发。 (在子指令之前)            

  • 我试图为我的模板创建一个覆盖,以自定义扩展在文章中显示其字段的方式。 我使用的扩展是DPfields,我使用的是开发人员提供的参考指南:https://joomla.digital-peak.com/documentation/162-dpfields/2750-rendering-fields 特别是我提到的段落:访问布局中的字段 我已经创建了一个新的php文件从default.php文件开始的

  • 问题内容: ModelMultipleChoiceField没有选择初始选择,并且在我的示例中,我无法进行以下修复 我的模型和表格: 我的工作和结果: 我希望它可以工作的方式: 1.我的视图从request.GET获取“公司” 2.然后过滤该“公司”的所有“联系人” 3.最后,它创建一个表单并将这些“联系人”作为“初始= {…}” 两个问题: 1. [尚未回答]如何使ModelMultipleCh

  • 是时候给这些网页来点动态特性了——用AngularJS!我们这里为后面要加入的控制器添加了一个测试。 一个应用的代码架构有很多种。对于AngularJS应用,我们鼓励使用模型-视图-控制器(MVC)模式解耦代码和分离关注点。考虑到这一点,我们用AngularJS来为我们的应用添加一些模型、视图和控制器。 请重置工作目录: git checkout -f step-2 我们的应用现在有了一个包含三部

  • 我有一个模板基类,其模板参数类型为bool。此基类的构造函数参数列表取决于模板参数是true还是false。我想从这个类派生另一个模板类,它的模板参数是任意类型的。我需要这个派生类根据该类型的特征调用该基类的正确构造函数。 下面的例子并不包罗万象。无论是否为整数,基类模板bool可以是任何类型trait。此外,传递给派生类的模板参数的类型可以是任何类型。