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+$')]">
我需要检查元素 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+$')]">