xslt将正则表达式中的数字添加到节点值

时间:2018-03-02 20:16:13

标签: xml xslt xml-parsing

我有以下xml片段:

<STMTTRN><TRNTYPE>PAYMENT</TRNTYPE>
<DTPOSTED>20171120</DTPOSTED>
<TRNAMT>-645.29</TRNAMT>
<FITID>2017112049840000000061890000000035</FITID>
<MEMO>ARGO SEGUROS  PARC 03/05 SAO PAULO   BR</MEMO>
</STMTTRN>

我想添加到DTPOSTED个节点x-1个月,其中xPARC后{前面两位数}所示的数字MEMO {1}}节点将由正则表达式(sed样式)提取

PARC \([0-9][0-9]\)/[0-9][0-9]

所以在上面的例子中,我想获得输出:

<STMTTRN><TRNTYPE>PAYMENT</TRNTYPE>
<DTPOSTED>20180120</DTPOSTED>
<TRNAMT>-645.29</TRNAMT>
<FITID>2017112049840000000061890000000035</FITID>
<MEMO>ARGO SEGUROS  PARC 03/05 SAO PAULO   BR</MEMO>
</STMTTRN>

我不知道如何继续,如果你能帮助我,我会很感激。

1 个答案:

答案 0 :(得分:2)

我准备了一个示例脚本,逐步显示如何获得结果 想。

由于此脚本使用xs命名空间,因此transform标记必须包含 xmlns:xs="http://www.w3.org/2001/XMLSchema"

它还必须包含exclude-result-prefixes="#all",否则输出 会包含xmlns:xs="http://www.w3.org/2001/XMLSchema"

基本逻辑包含在模板匹配DTPOSTED中。 在我的脚本中打印:

  • DTPOSTED的原始内容。
  • 所有中间值(以/分隔)。
  • 最终值(移位日期字符串)。

在您的脚本中省略除最后一个和任何之外的任何xsl:value-of xsl:text用作分隔符。

现在让我们来看看细节:

  • replace函数替换整个文本的内容 第一个捕获组,在您的情况下为03
  • 要删除前导0,我使用了number函数,现在我们已经使用了P 要添加的月数(到目前为止,未减少)。
  • 持续时间字符串由3部分组成:
    • xs:date - 期间指标,
    • 上述月数 - 1,
    • 'M' - 单位指标(月)。
  • 为了执行日期算术,我们需要原始日期, 转换为d1类型。我将其存储在$d1 + xs:yearMonthDuration($dur)变量中。
  • 根据公式计算移位日期 d2。我将其存储在$d2变量中。
  • 最后一个阶段是打印-,但没有<?xml version="1.0" encoding="UTF-8" ?> <xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all"> <xsl:output method="xml" encoding="UTF-8" indent="yes" /> <xsl:template match="DTPOSTED"> <DTPOSTED> <xsl:value-of select="."/> <!-- Original value (string) --> <xsl:text> / </xsl:text> <!-- Duration (string) --> <xsl:variable name="dur" select="concat('P', number(replace(../MEMO,'\D+(\d\d)/.+','$1')) - 1, 'M')"/> <xsl:value-of select="$dur"/> <xsl:text> / </xsl:text> <!-- Original value (date) --> <xsl:variable name="d1" select="xs:date(concat(substring(., 1, 4), '-', substring(., 5, 2), '-', substring(., 7, 2)))"/> <xsl:value-of select="$d1"/> <xsl:text> / </xsl:text> <!-- "Shifted" date --> <xsl:variable name="d2" select="$d1 + xs:yearMonthDuration($dur)"/> <xsl:value-of select="$d2"/> <xsl:text> / </xsl:text> <!-- "Shifted" date without '-' chars --> <xsl:value-of select="format-date($d2, '[Y0001][M01][D01]')"/> </DTPOSTED> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> </xsl:template> </xsl:transform> 个字符。

所以整个脚本如下所示:

DTPOSTED

对于您的示例来源,它会将<DTPOSTED>20171120 / P2M / 2017-11-20 / 2018-01-20 / 20180120</DTPOSTED> 打印为:

20171120

如前所述,它包含:

  • P2M - 原始字符串。
  • 2017-11-20 - 句号字符串。
  • 2018-01-20 - 原始日期。
  • - - 转移日期(20180120个字符)。
  • - - 将日期换成字符串,没有@Query("SELECT a FROM ArticlesEntity a " + "WHERE ((:approved = 2 ) or (a.approved = :approved)) ") Page<ArticlesEntity> filterByAllPage( @Param("approved") Byte approved, Pageable pageable); 字符。

实际上你只需要上面打印的最后一个。