xslt将正则表达式中的数字添加到节点值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了xslt将正则表达式中的数字添加到节点值相关的知识,希望对你有一定的参考价值。
我有以下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
函数,所以现在我们有几个月要添加(到目前为止,没有减少)。 - 持续时间字符串由3部分组成:
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+(dd)/.+','$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
- 原始日期。- qazxsw poi - 轮班日期(与qazxsw poi排行榜)。
2018-01-20
- 将日期换成字符串,没有-
字符。
实际上你只需要上面打印输出中的最后一个。
以上是关于xslt将正则表达式中的数字添加到节点值的主要内容,如果未能解决你的问题,请参考以下文章