XSLT - regex select only one digit number from text() node

女生的网名这么多〃 提交于 2019-12-02 13:23:15

If you define a "single digit number" as a single digit surrounded by non-digit characters, you can then use:

<xsl:template match="para/text()">
    <xsl:analyze-string select="." regex="(\D)(\d)(\D)">

    <xsl:matching-substring>
        <xsl:value-of select="regex-group(1)"/>
        <xsl:value-of select="2 * number(regex-group(2))"/>
        <xsl:value-of select="regex-group(3)"/>
    </xsl:matching-substring>

    <xsl:non-matching-substring>
        <xsl:value-of select="."/>
    </xsl:non-matching-substring>

    </xsl:analyze-string>
</xsl:template>

Note that this does not capture single-digit numbers at the beginning or at the end of the string. To include these, you would have to use:

<xsl:analyze-string select="." regex="(^|\D)(\d)(\D|$)">

There are several ways to solve the problem. One way is to require that the single digit is followed by "cm" (if that's always the case in your input XML, we don't know yet).

XSLT Stylesheet

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="para/text()">
        <xsl:analyze-string select="." regex="\dcm">

            <xsl:matching-substring>
                <xsl:value-of select="2 * number(substring-before(.,'cm'))"/>
            </xsl:matching-substring>

            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>

        </xsl:analyze-string>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:transform>

XML Output

<section>
    <para>height 8, width 10, weight 343</para>
    <para>height 4, width 12, weight 410</para>
    <para>height 6, width 2, weight 590</para>
</section>

Alternatively, you could e.g. require that the single digit is followed by something that is not a digit:

<xsl:template match="para/text()">
    <xsl:analyze-string select="." regex="\d[^\d]">

        <xsl:matching-substring>
            <xsl:value-of select="2 * number(substring(.,1,1))"/>
        </xsl:matching-substring>

        <xsl:non-matching-substring>
            <xsl:value-of select="."/>
        </xsl:non-matching-substring>

    </xsl:analyze-string>
</xsl:template>

If that always applies to your data, because it does not cover cases where there is a single digit at the very end of a string.


To account for all possible cases, use

<xsl:template match="para/text()">
    <xsl:analyze-string select="." regex="(^|[^\d])(\d)([^\d]|$)">

        <xsl:matching-substring>
            <xsl:value-of select="regex-group(1)"/>
            <xsl:value-of select="2 * number(regex-group(2))"/>
            <xsl:value-of select="regex-group(3)"/>
        </xsl:matching-substring>

        <xsl:non-matching-substring>
            <xsl:value-of select="."/>
        </xsl:non-matching-substring>

    </xsl:analyze-string>
</xsl:template>

which is essentially the same as michael.hor257k has suggested (before I did!).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!