我有以下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
月,其中x
是PARC
节点中MEMO
之后的前两位数表示的数字,将由正则表达式提取(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>
我不知道如何继续,如果你能帮助我,我会很感激。
我准备了一个示例脚本,逐步显示如何获得所需的结果。
因为此脚本使用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
- 期间指标,
上述月份数 - 1,
'M' - 单位指标(月)。xs:date
类型。我把它存储在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
- 将日期换成字符串,没有-
字符。实际上你只需要上面打印输出中的最后一个。