XPath - 从字符串中提取数值

时间:2021-05-11 20:04:05
<Description>this is my value 822880494 this is my value</Description>

I'm quite new to xpath, xml and stylevision so this might be a basic problem.

我对xpath,xml和stylevision很新,所以这可能是一个基本问题。

I am using stylevision 2010 and xpath to create an sps/xslt for an schema.

我正在使用stylevision 2010和xpath为模式创建sps / xslt。

In the above node you can see there is a numeric value inside the node and I want to extract that value and turn it into a link in my pdf/html. The problem is that i cant seem to extract it. Substring is not an option since the length of the value and the position of the numeric value inside it varies.

在上面的节点中,您可以看到节点内部有一个数值,我想提取该值并将其转换为我的pdf / html中的链接。问题是我似乎无法提取它。子字符串不是一个选项,因为值的长度和其中数值的位置会有所不同。

Some will probably think that the schema is badly composed and that the numeric value should be in a seperate node/attribute/... There is nothing I can do about that since this schema is provided by another company.

有些人可能会认为模式组成严重,数值应该在一个单独的节点/属性/ ...中我无能为力,因为这个模式是由另一家公司提供的。

Thanks in advance!

提前致谢!

4 个解决方案

#1


8  

StyleVision 2010 seems to support XSLT 2.0, so you could use a 2.0 stylesheet and do something like

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>

Or whatever you want to do with the number; the string with the number is the context element inside the <xsl:matching-substring> element.

或者你想用这个号码做什么;带有数字的字符串是 元素中的上下文元素。 :matching-substring>

Newtover's translate idea (for XSLT 1.0) would look like this:

Newtover的翻译想法(对于XSLT 1.0)看起来像这样:

<xsl:value-of select="translate(., translate(., '0123456789', ''), '')" />

But if your input contains multiple numbers, that will simply concatenate them.

但是,如果您的输入包含多个数字,那么只需将它们连接起来。

#2


13  

Use this simple XPath 1.0 expression:

使用这个简单的XPath 1.0表达式:

translate(.,translate(., '0123456789', ''), '')

Here is a complete XSLT 1.0 solution:

这是一个完整的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>

when this transformation is applied on the provided XML document:

当此转换应用于提供的XML文档时:

<Description>this is my value 822880494 this is my value</Description>

the wanted, correct result is produced:

产生了想要的正确结果:

822880494

Explanation:

说明:

This is known as the Double Translate Method first proposed by Michael Kay. It consists of two nested calls to the translate() function:

这被称为Michael Kay首先提出的Double Translate Method。它由对translate()函数的两个嵌套调用组成:

  1. Inner translate(). This produces all characters of the string, except digits.

    内翻()。这将生成字符串的所有字符,但数字除外。

  2. Outer translate(). This deletes from the string all characters produced by the inner translate(). What remains is just the wanted characters (the digits).

    外翻()。这将从字符串中删除内部translate()生成的所有字符。剩下的只是想要的字符(数字)。

#3


2  

A fragile but possible solution in plain XSLT 1.0 would be to use a composition of translate (to make all non-numeric values to empty strings or spaces) and normalize-space (to trim the rest of spaces, though translate might suffice). This will certainly work only if there are no other numeric values within the string. And, I can't currently check, translate might work only if your string contains ascii characters.

普通XSLT 1.0中一个脆弱但可能的解决方案是使用translate的组合(使所有非数字值为空字符串或空格)和normalize-space(以修剪其余空格,尽管translate可能就足够了)。只有在字符串中没有其他数值时,这肯定会起作用。而且,我目前无法检查,只有当您的字符串包含ascii字符时,translate才有效。

XSLT 2.0 has several regexp functions. If you xslt processor allows using EXSLT extentions, it as well contains regexp functions, or you can tokenize your string by spaces and provide non-empty template to the numeric token only.

XSLT 2.0有几个regexp函数。如果xslt处理器允许使用EXSLT扩展,它也包含regexp函数,或者您可以通过空格对字符串进行标记,并仅为数字标记提供非空模板。

p.s. I am sorry, that I do not provide any links, it's hard to to from the device.

附:对不起,我没有提供任何链接,很难从设备中获取。

#4


2  

hi this will produce the results you requre! it checks each character, and then makes sure that it is a number.

嗨,这将产生你需要的结果!它检查每个字符,然后确保它是一个数字。

XSLT 1 Solution

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) &gt; 0">
                <xsl:if test="substring($data,1,1)&gt;-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>

#1


8  

StyleVision 2010 seems to support XSLT 2.0, so you could use a 2.0 stylesheet and do something like

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>

Or whatever you want to do with the number; the string with the number is the context element inside the <xsl:matching-substring> element.

或者你想用这个号码做什么;带有数字的字符串是 元素中的上下文元素。 :matching-substring>

Newtover's translate idea (for XSLT 1.0) would look like this:

Newtover的翻译想法(对于XSLT 1.0)看起来像这样:

<xsl:value-of select="translate(., translate(., '0123456789', ''), '')" />

But if your input contains multiple numbers, that will simply concatenate them.

但是,如果您的输入包含多个数字,那么只需将它们连接起来。

#2


13  

Use this simple XPath 1.0 expression:

使用这个简单的XPath 1.0表达式:

translate(.,translate(., '0123456789', ''), '')

Here is a complete XSLT 1.0 solution:

这是一个完整的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>

when this transformation is applied on the provided XML document:

当此转换应用于提供的XML文档时:

<Description>this is my value 822880494 this is my value</Description>

the wanted, correct result is produced:

产生了想要的正确结果:

822880494

Explanation:

说明:

This is known as the Double Translate Method first proposed by Michael Kay. It consists of two nested calls to the translate() function:

这被称为Michael Kay首先提出的Double Translate Method。它由对translate()函数的两个嵌套调用组成:

  1. Inner translate(). This produces all characters of the string, except digits.

    内翻()。这将生成字符串的所有字符,但数字除外。

  2. Outer translate(). This deletes from the string all characters produced by the inner translate(). What remains is just the wanted characters (the digits).

    外翻()。这将从字符串中删除内部translate()生成的所有字符。剩下的只是想要的字符(数字)。

#3


2  

A fragile but possible solution in plain XSLT 1.0 would be to use a composition of translate (to make all non-numeric values to empty strings or spaces) and normalize-space (to trim the rest of spaces, though translate might suffice). This will certainly work only if there are no other numeric values within the string. And, I can't currently check, translate might work only if your string contains ascii characters.

普通XSLT 1.0中一个脆弱但可能的解决方案是使用translate的组合(使所有非数字值为空字符串或空格)和normalize-space(以修剪其余空格,尽管translate可能就足够了)。只有在字符串中没有其他数值时,这肯定会起作用。而且,我目前无法检查,只有当您的字符串包含ascii字符时,translate才有效。

XSLT 2.0 has several regexp functions. If you xslt processor allows using EXSLT extentions, it as well contains regexp functions, or you can tokenize your string by spaces and provide non-empty template to the numeric token only.

XSLT 2.0有几个regexp函数。如果xslt处理器允许使用EXSLT扩展,它也包含regexp函数,或者您可以通过空格对字符串进行标记,并仅为数字标记提供非空模板。

p.s. I am sorry, that I do not provide any links, it's hard to to from the device.

附:对不起,我没有提供任何链接,很难从设备中获取。

#4


2  

hi this will produce the results you requre! it checks each character, and then makes sure that it is a number.

嗨,这将产生你需要的结果!它检查每个字符,然后确保它是一个数字。

XSLT 1 Solution

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) &gt; 0">
                <xsl:if test="substring($data,1,1)&gt;-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>