XSLT - 正则表达式 select 只有来自 text() 节点的一位数字

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

我已经xml这样了,

<section>
    <para>height 4cm, width 5cm, weight 343</para>
    <para>height 2cm, width 6cm, weight 410</para>
    <para>height 3cm, width 1cm, weight 590</para>
</section>

这里我需要将para/text()的个位数加倍。所需的输出应该看起来像,

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

为此,我有一个这样的模板,

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

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

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

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

这里的问题是这样的,这个把none个数一位一位地加倍,

当前输出,

<section>
    <para>height 8cm, width 10cm, weight 686</para>
    <para>height 4cm, width 12cm, weight 820</para>
    <para>height 6cm, width 2cm, weight 10180</para>
</section>

有什么建议可以解决这个问题吗?

有几种方法可以解决这个问题。一种方法是要求单个数字后跟 "cm"(如果您输入的 XML 总是这样,我们还不知道)。

XSLT 样式表

<?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输出

<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>

或者,您可以例如要求单个数字后跟非数字的内容:

<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>

如果这始终适用于您的数据,因为它不包括字符串末尾只有一个数字的情况。


要考虑所有可能的情况,请使用

<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>

这与 michael.hor257k 所建议的基本相同(在我之前!)。

如果将 "single digit number" 定义为被 non-digit 个字符包围的单个数字,则可以使用:

<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>

请注意,这不会捕获字符串开头或结尾的 single-digit 数字。要包含这些,您必须使用:

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