XSLT 将 regex-group() 值传递给变量并对其进行格式化

XSLT pass regex-group() value to variable and formatting it

我还没有找到关于如何执行此操作的明确示例。 我想将 2 个正则表达式组结果传递给分析字符串中的变量,其中一个应该从十六进制转换为十进制。例如,使用 regex-group(2)=2 和 regex-group(4)=30,regex-group(4) 应该被格式化为 0.30 传递给变量的两个值让我们说 $rg2 $rg4 然后计算 "($rg4* (100 div 60))+$rg2" "(0.30*(100 div 60))+2"=2.5 。如果 rg4=0.38 那么最终结果将是 2.6333333333333333

    <xsl:analyze-string select="sbtime/@stmerid" regex="([hm]{{1}})([0-9]{{1,2}})([ew]{{1}})([0-9]{{0,2}})">
        <xsl:matching-substring>
            <xsl:choose>
                <xsl:when test="regex-group(1) = 'm'">
                    <xsl:choose>
                        <xsl:when test="regex-group(3) = 'e'">
                            <xsl:text>-</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>+</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                    <xsl:choose>
                        <xsl:when test="regex-group(4) != ''">
                            <xsl:text>:</xsl:text>
                            <xsl:variable name="rg2" as="xs:float">{regex-group(2)}</xsl:variable>
                            <xsl:variable name="rg4" as="xs:float">fn:format-number({regex-group(4)},'#.##')</xsl:variable>
                            <xsl:value-of select="($rg4*(100 div 60))+$rg2"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:number value="regex-group(2)" format="1"/>
                        </xsl:otherwise>
                    </xsl:choose>
                    <xsl:number value="regex-group(2)" format="1"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:choose>
                        <xsl:when test="regex-group(3) = 'e'">
                            <xsl:text>-</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>+</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                    <xsl:if test="regex-group(1) = 'm'"><xsl:text>00:</xsl:text></xsl:if>
                    <xsl:number value="regex-group(2)" format="1"/>
                    <xsl:choose>
                        <xsl:when test="regex-group(4) != ''">
                            <xsl:text>:</xsl:text>
                            <xsl:number value="regex-group(4)" format="1"/>
                        </xsl:when>
                        <xsl:otherwise>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:matching-substring>
    </xsl:analyze-string>

如何做到这一点?可能有一种干净快速的方法。 我不知道你是否必须使用变量,或者在 xslt 中是否存在范围和转换​​值的问题。

编辑:我想我问这个问题是因为我最初尝试过这个:

<xsl:variable name="rg2" select="regex-group(2)"/>
<xsl:variable name="rg4" select="regex-group(4)"/>
<xsl:value-of select="((0.$rg4)*(100 div 60))+$rg2"/>

并在 xmlspy 中返回 "not a valid instance of the x-path grammar" 我不确定如何处理数字和数学以添加“0”。在 $rg4 前面像一个字符串。

绑定 XPath 表达式求值结果的语法(类似于 regex-group(2) 的函数调用)很简单

<xsl:variable name="rg2" select="regex-group(2)"/>

<xsl:variable name="rg2" as="xs:float">{regex-group(2)}</xsl:variable> 可能会在 XSLT 3.0 中设置 expand-text="yes"

一般来说,如果您有一个字符串(例如 regex-group() 返回的字符串)并且需要特定类型的数字,则调用构造函数,例如

<xsl:variable name="rg2" select="xs:decimal(regex-group(2))"/>

对于你的算术计算 ($rg4*(100 div 60))+$rg2 你需要两个数值而 format-number 会给你一个字符串所以我猜你更想定义

<xsl:variable name="rg4" select="xs:decimal(regex-group(4)) div 100"/>

我没能完全理解你想做的事情,但是当你写的时候

<xsl:value-of select="((0.$rg4)*(100 div 60))+$rg2"/>

那么我认为您误解了变量在 XSLT 中的工作方式。变量是可以在需要表达式的地方使用的命名值,它们不是可以在文本中的任何地方替换的字符串(也就是说,它们不是宏)。

如果 $rg4 是字符串“30”并且您想要值 0.30,那么您想要的不是 0.$rg4,而是 xs:decimal(concat("0.", $rg4))