XSLT选择一个文本包含格式为“1.1.1”的数字的元素

时间:2015-01-29 18:03:20

标签: xml xslt

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

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

1 个答案:

答案 0 :(得分:0)

你真的应该尝试一下。在这样的问题中,只转换XML的一部分(在您的情况下,将el更改为h3并删除b),您应立即思考&#34;啊哈!身份变换&#34; (见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时,没有一种方便的方式来识别&#34;数字&#34;格式为1.1.1。如果您想要混淆令人困惑的表达式,可以使用以下方法匹配您的el元素,然后将其替换为h3元素。

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

你会有一个类似的用于匹配,然后删除b下面的el元素

<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+$')]">