我是这样的xml,
John: 8 Coke
Mary: 1 Pie
Mary: 2 Water
Jack: 3 Milk
这里我需要将<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>
任何建议如何解决这个问题?
答案 0 :(得分:4)
有几种方法可以解决这个问题。一种方法是要求单个数字后跟&#34; cm&#34; (如果输入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提出的基本相同(在我做之前!)。
答案 1 :(得分:2)
如果您定义一个&#34;单个数字&#34;作为由非数字字符包围的单个数字,您可以使用:
<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>
请注意,这不会捕获字符串开头或结尾的单位数字。要包含这些,您必须使用:
<xsl:analyze-string select="." regex="(^|\D)(\d)(\D|$)">