<Description>this is my value 822880494 this is my value</Description>
我对xpath,xml和stylevision都很陌生,所以这可能是一个基本问题。
我正在使用stylevision 2010和xpath为架构创建sps / xslt。
在上面的节点中,您可以看到节点内部有一个数值,我想提取该值并将其转换为我的pdf / html中的链接。问题是我似乎无法提取它。子字符串不是一个选项,因为值的长度和其中数值的位置会有所不同。
有些人可能会认为模式组成严重,数值应该在一个单独的节点/属性中......由于这个模式是由另一家公司提供的,所以我无能为力。
提前致谢!
答案 0 :(得分:14)
使用这个简单的XPath 1.0表达式:
translate(.,translate(., '0123456789', ''), '')
这是一个完整的XSLT 1.0解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:value-of select=
"translate(.,translate(., '0123456789', ''), '')"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档:
<Description>this is my value 822880494 this is my value</Description>
产生了想要的正确结果:
822880494
<强>解释强>:
这被称为Michael Kay首先提出的 Double Translate Method 。它包含两个对translate()
函数的嵌套调用:
内部translate()
。这会生成字符串的所有字符,但数字除外。
外translate()
。这将从字符串中删除内部translate()
生成的所有字符。剩下的只是想要的字符(数字)。
答案 1 :(得分:8)
StyleVision 2010似乎支持XSLT 2.0,因此您可以使用2.0样式表并执行类似
的操作<xsl:analyze-string select='$foo' regex='\d+'>
<xsl:matching-substring>
<number><xsl:value-of select='.' /></number>
</xsl:matching-substring>
</xsl:analyze-string>
或者你想用这个号码做什么;带有数字的字符串是<xsl:matching-substring>
元素中的上下文元素。
Newtover的translate
想法(对于XSLT 1.0)看起来像这样:
<xsl:value-of select="translate(., translate(., '0123456789', ''), '')" />
但如果您的输入包含多个数字,那么只需将它们连接起来。
答案 2 :(得分:2)
普通XSLT 1.0中一个脆弱但可能的解决方案是使用translate
的组合(使所有非数字值为空字符串或空格)和normalize-space
(以修剪剩下的空格,虽然translate
可能就足够了)。只有在字符串中没有其他数值时,这肯定会起作用。而且,我目前无法检查,translate
可能仅在您的字符串包含ascii字符时才有效。
XSLT 2.0有几个regexp功能。如果你的xslt处理器允许使用EXSLT扩展,它也包含regexp函数,或者你可以用空格标记你的字符串,并且只为数字标记提供非空模板。
P.S。对不起,我没有提供任何链接,很难从设备上获取。
答案 3 :(得分:2)
嗨,这将产生您需要的结果!它检查每个字符,然后确保它是一个数字。
XSLT 1解决方案
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Root/Description">
<xsl:call-template name="for-each-character">
<xsl:with-param name="data" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="for-each-character">
<xsl:param name="data"/>
<xsl:if test="string-length($data) > 0">
<xsl:if test="substring($data,1,1)>-1">
<xsl:value-of select="substring($data,1,1)"/>
</xsl:if>
<xsl:call-template name="for-each-character">
<xsl:with-param name="data" select="substring($data,2)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 4 :(得分:0)
以下是上述XSLT v1解决方案的派生产品,但是,这是专门针对前导数字的,而不是嵌入在字符串的中间。它还允许进行浮点或整数解析。 (我个人认为这对于将单位与“ 80 mg”或“ 128.4 mm2”(其中单位为“ mm2”,值“ 128.4”,而不是“ 128.42”)分开是很有用的。
<xsl:template name="parseNumber">
<xsl:param name="data"/>
<xsl:param name="is-float" select="false()"/><!-- has this already been determined to be a non-integer -->
<xsl:if test="string-length($data) > 0">
<xsl:if test="(substring($data,1,1)>-1) or ((substring($data,1,1) = '.') and (not($is-float)) )">
<xsl:value-of select="substring($data,1,1)"/>
<xsl:call-template name="parseNumber">
<xsl:with-param name="data" select="substring($data,2)"/>
<xsl:with-param name="is-float" select="(substring($data,1,1) = '.') or ($is-float)"/>
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:template>
以下是一些具有比较结果的单元测试案例:
Test: [123] ?=? numer(): [123] ?=? for-each-char: [123] ?=? parseNumber: [123]
Test: [1.23] ?=? numer(): [1.23] ?=? for-each-char: [1.23] ?=? parseNumber: [1.23]
Test: [1.1.1.1] ?=? numer(): [NaN] ?=? for-each-char: [1.1.1.1] ?=? parseNumber: [1.1]
Test: [123 abc] ?=? numer(): [NaN] ?=? for-each-char: [123] ?=? parseNumber: [123]
Test: [123 abc2] ?=? numer(): [NaN] ?=? for-each-char: [1232] ?=? parseNumber: [123]
Test: [123.456 abc7] ?=? numer(): [NaN] ?=? for-each-char: [123.4567] ?=? parseNumber: [123.456]
Test: [abc def ] ?=? numer(): [NaN] ?=? for-each-char: [] ?=? parseNumber: []
Test: [abc 123] ?=? numer(): [NaN] ?=? for-each-char: [123] ?=? parseNumber: []