使用Java将本地参数传递给XSLT中的全局参数

时间:2019-09-06 19:15:46

标签: java xslt parameter-passing

在我的For-each循环中,两列分别为Division(字符串)和Paydate(日期)。

完成For-each循环后,我会写一条偏移线,以使要创建的日记帐分录处于平衡状态。但是,我需要在偏移线上包括“分部”和“付款日期”。由于这两个值仅“存在”于For-each循环内,所以我在偏移线上不可用。

是否有人有使用Java params函数(MSXSL版本)的经验,他们已将参数从For-each内部传递给全局参数?

我尝试更新For-each内部的全局变量,首先尝试在全局和本地定义它,然后再通过局部定义全局变量。从那以后,我了解到XSL变量不是变量(对不起,我是一个古老的RPG编码器,对我来说这是gnu的东西)。

<!-- Global param -->
<xsl:param name = "DiviG"/>

<!-- Choose to populate local variable -->
<xsl:choose>
<xsl:when test="PayGroupxRef='11DD_B' or PayGroupxRef='11DD_Hourly'">
<xsl:variable name = "Divi">504</xsl:variable>
</xsl:when>

每次运行只有一个PayGroupxRef和PayPeriodDate。我需要将这两个值放在For-each循环的每一行以及偏移行上。

Division    PayDate     Amount
504     09/06/19    +10.00
504     09/06/19    +20.00
504     09/06/19    -30.00

XML输入是由我无法控制的单独函数生成的。它是一个工资期的工资数据,其中包含我可以访问的有限数量的标签,例如PayGroupxRef是“付款组”表中定义的外部参考值,“付款日期”是令牌payrun_pay_date。

输出是我需要在提取的每一行以及Payrun_Pay_Date上通过case语句转换的PayGroupxRef。处理完输入中的每条记录后,我需要再写一行,其中每一行都包含来自For-each循环(对于gauche术语表示歉意)中的总金额的负数,以及PayGroupxRef和PayDate。总结这件作品很好,这是我缺少的最后两件作品。

XSLT的缩写代码:

<!-- Headers -->
<xsl:text>Divi,</xsl:text>
<xsl:text>Acc Date,</xsl:text>
<xsl:text>&#x0D;&#x0A;</xsl:text>

<!-- Details -->
<xsl:for-each select="Export/Record[Amount!=0] and AccrualType='AC'">
<xsl:choose>
    <xsl:when test="PayGroupxRef='11DD_B' or    PayGroupxRef='11DD_Hourly'">`
        <xsl:text>504</xsl:text>
        <xsl:variable name="Divi">504</xsl: variable>
    </xsl:when>
    <xsl:when test="PayGroupxRef='11DI_B'">
        <xsl:text>XXX</xsl:text>
        <xsl:variable name="Divi">XXX</xsl: variable>
    </xsl:when>
    <xsl:when test="PayGroupxRef='11DF_B' or PayGroupxRef='11DC_B'">
        <xsl:text>510</xsl:text>
        <xsl:variable name="Divi">510</xsl: variable>
    </xsl:when>
    <xsl:when test="PayGroupxRef='11DH_W' or PayGroupxRef='11DD_B'">
        <xsl:text>40R</xsl:text>
        <xsl:variable name="Divi">40R</xsl: variable>
    </xsl:when>
    <xsl:when test="PayGroupxRef='11DB_B' or PayGroupxRef='11DA_B'">
        <xsl:text>50A</xsl:text>
        <xsl:variable name="Divi">50A</xsl: variable>
    </xsl:when>
    <xsl:when test="PayGroupxRef='11DE_B'">
        <xsl:text>500</xsl:text>
        <xsl:variable name="Divi">500</xsl: variable>
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>???</xsl:text>
        <xsl:variable name="Divi">???</xsl: variable>
    </xsl:otherwise>
<xsl:value-of select="PayDate"/>
<xsl:text>&#x0D;&#x0A;</xsl:text>
</xsl:for-each>

<!-- Write the offset line -->
<xsl:copy-of select="Divi"/>
<xsl:value-of select="PayDate"/>
</xsl:template>
</xsl:stylesheet>

我可以在For-each循环中看到可变的$ Divi,但是如果我尝试在循环外使用它(如果我使用不正确的术语,则表示歉意),它表示$ Divi没有定义。

2 个答案:

答案 0 :(得分:0)

您显然在为XSLT所使用的函数式编程范式而苦苦挣扎:您在考虑“循环”和“更新”方面的知识,而您忘记了小学数学,而在{{1 }},area=length*widthlength之所以称为变量,是因为它们对于不同的矩形是不同的,而不是因为矩形在您进行计算时会改变形状。

现在的问题是,您已经从获取答案的过程代码(实际上是没有得到答案的残破代码),而不是输入,输出,和他们的关系。将无法正常工作的代码反向转换为对该问题的高级说明并不是一件容易的事,也没有必要。向我们展示输入,向我们展示输出,解释它们之间的关系,您已经提供了对该问题的功能描述,通常可以很自然地转化为功能解决方案。

答案 1 :(得分:0)

总的来说,我第一个建议想到的方法是使用XML作为中介存储,例如

<xsl:variable name="lines-rtf">
<xsl:for-each select="Export/Record[Amount!=0] and AccrualType='AC'">
  <record>
    <divi>
<xsl:choose>
    <xsl:when test="PayGroupxRef='11DD_B' or    PayGroupxRef='11DD_Hourly'">`
        <xsl:text>504</xsl:text>
    </xsl:when>
    <xsl:when test="PayGroupxRef='11DI_B'">
        <xsl:text>XXX</xsl:text>
    </xsl:when>
    <xsl:when test="PayGroupxRef='11DF_B' or PayGroupxRef='11DC_B'">
        <xsl:text>510</xsl:text>
    </xsl:when>
    <xsl:when test="PayGroupxRef='11DH_W' or PayGroupxRef='11DD_B'">
        <xsl:text>40R</xsl:text>
    </xsl:when>
    <xsl:when test="PayGroupxRef='11DB_B' or PayGroupxRef='11DA_B'">
        <xsl:text>50A</xsl:text>
    </xsl:when>
    <xsl:when test="PayGroupxRef='11DE_B'">
        <xsl:text>500</xsl:text>
    </xsl:when>
 </xsl:choose>
</divi>
  <paydate>
    <xsl:value-of select="PayDate"/>
  </paydate>
 </record>
</xsl:for-each>
</xsl:variable>

现在,在大多数XSLT 1.0处理器中,该变量具有结果树片段类型的值,并且要允许您在其上使用XPath,您需要首先使用扩展功能,大多数XSLT 1处理器都支持

<xsl:variable name="lines" select="exsl:node-set($lines-rtf)" xmlns:exsl="http://exslt.org/common"/>

对于某些(尤其是MSXML),您需要在特定于该特定供应商或处理器的专有名称空间中使用类似的扩展功能。

然后,您可以使用<xsl:value-of select="$lines/record[last()]/divi"/>输出摘要,并通过模板或其他for-each输出运行变量的行。

您是否需要中间XML,因为我没有看到XML的初始输入,所以我不太确定,因此我不确定是否仅选择其中一个就足以提取所需的内容。但是通常,如果要存储多个值,可以使用XML来实现,然后仅在XSLT 1中借助扩展功能,就可以根据需要进一步处理该中间XML。

在XSLT 2/3中,事情变得更加轻松和紧凑,在XSLT 2/3中,您可以使用xsl:value-of属性,separator函数和用户定义的函数来拥有更强大的string-join

因此,如果您使用的Java在任何情况下都比Oracle JRE内置的Xalan XSLT 1处理器更好地开发和维护了Saxon 9,则应该考虑使用Saxon 9迁移到XSLT 2/3,并且某些东西花费更少的钱代码,减少头痛。尽管从程序编程到声明式/函数式编程的适应是您无论如何都需要进行的步骤。

相关问题