XSLT select 文本元素包含格式为“1.1.1”的数字

XSLT select an element with text containing number in format "1.1.1"

我需要检查元素 el 是否包含格式为 1.1.1 的文本。如何识别这个el元素?

<root>
  <story>
    <el>1.1.1 <b>head1</b></el>
    <el>some text</el>
    <el>1.1.1 <b>head1</b></el>
    <el>some text</el>
    <el>1.10.2<b>head1</b></el>
    <el>some text</el>
    <el>19.9.10<b>head1</b></el>
 </story>
</root>

如有任何帮助,我们将不胜感激。 好吧,我希望得到以下结果:

<root>
  <story>
    <h3>1.1.1 head1</h3>
    <el>some text</el>
    <h3>1.1.1 head1</h3>
    <el>some text</el>
    <h3>1.10.2 head1</h3>
    <el>some text</el>
    <h3>19.9.10 head1</h3>
  </story>
</root>

你真的应该尝试一下。在像这样的问题中,您只转换 XML 的一部分(在您的情况下,将 el 更改为 h3 并删除 b),您应该立即想到 "Aha! Identity Transform"(参见 http://en.wikipedia.org/wiki/Identity_transform)。这意味着从这个模板开始

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

那么,你已经成功了一半!然后您只需要编写模板来更改您确实需要的节点(它应该优先于通用身份模板)。

现在,当您使用 XSLT 1.0 时,没有一种方便的方法来识别格式 1.1.1 中的 "number"。如果您想喜欢混淆表达式,这里有一种匹配 el 元素的方法,然后将 then 替换为 h3 元素。

<xsl:template match="el[normalize-space(concat('[', translate(translate(normalize-space(text()), ' ', '_'), '1234567890', '          '), ']')) = '[ . . ]']">
    <h3>
        <xsl:apply-templates select="@*|node()"/>
    </h3>
</xsl:template>

您将有一个类似的匹配,然后删除 el

下方的 b 元素
<xsl:template match="el[normalize-space(concat('[', translate(translate(normalize-space(text()), ' ', '_'), '1234567890', '          '), ']')) = '[ . . ]']/b">
    <xsl:text> </xsl:text>
    <xsl:apply-templates />
</xsl:template>

但是,这意味着对可怕的表达式进行两次编码,因此另一种方法是在模板调用中使用 mode 属性。

试试这个 XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="el[normalize-space(concat('[', translate(translate(normalize-space(text()), ' ', '_'), '1234567890', '          '), ']')) = '[ . . ]']">
        <h3>
            <xsl:apply-templates select="@*|node()" mode="b"/>
        </h3>
    </xsl:template>

    <xsl:template match="b" mode="b">
        <xsl:text> </xsl:text>
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="@*|node()" mode="b">
        <xsl:call-template name="identity" />
    </xsl:template>

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

请注意,在 XSLT 2.0 中,您可以使用 matches 函数

<xsl:template match="el[matches(normalize-space(text()), '^\d+\.\d+\.\d+$')]">