2013-05-08 42 views
1

我尝试从一个元素或字符串的函数确定所有的数字。数字和他们的统计数字应该没有关系。我以前写 以下功能:如何找到所有的数字字符串中的

<xsl:function name="itp:find_num"> 
<xsl:param name="tmp"/> 
<xsl:if test="matches($tmp,'\d+')"> 
    <xsl:analyze-string select="$tmp" regex="{'\d+'}"> 
     <xsl:matching-substring> 
      <xsl:sequence select="."/> 
     </xsl:matching-substring> 
     <xsl:non-matching-substring> 
      <xsl:value-of select="''"/> 
     </xsl:non-matching-substring> 
    </xsl:analyze-string> 
</xsl:if> 
</xsl:function> 

示例XML:

<address>street 12, 12345 town<address> 

在函数调用应该是适当的数目可被选择:

...select="itp:find_num(address)[2]"/> 

例如,2为邮编。 的问题是,空值是这样的序列中,我在实践中实现邮政编码只[4]。

有没有解决我的问题更优雅的方式? 如果不是,我如何从序列中删除空元素?

英语

现在:-)

我试图找到一个字符串或元素的所有数字。它不应该不管有多少编号或在哪个位置他们是在字符串中。

这里是我的功能:

<xsl:function name="itp:find_num"> 
<xsl:param name="tmp"/> 
<xsl:if test="matches($tmp,'\d+')"> 
    <xsl:analyze-string select="$tmp" regex="{'\d+'}"> 
     <xsl:matching-substring> 
     <xsl:if test=". != ''"> 
      <xsl:sequence select="."/> 
     </xsl:if> 
     </xsl:matching-substring> 
     <xsl:non-matching-substring> 
      <xsl:value-of select="''"/> 
     </xsl:non-matching-substring> 
    </xsl:analyze-string> 
</xsl:if> 
</xsl:function> 

示例XML

<address>street 12, 12345 town<address> 

当我调用我想选择的功能,我想选择哪个号码:

...select="itp:find_num(address)[2]"/> 

帕示例[2]的邮政编码。 这个问题我有是,thatthere是序列中的空元素,所以我才不得不选择[4],以获得邮政编码。

有没有解决我的问题一个更简单的方法? 或者有什么办法可以按照这个顺序删除所有空元素?

感谢:-)

+0

Christian Manthey,您可能对更简单,更短,纯粹的XPath解决方案感兴趣。 – 2013-05-08 14:40:13

回答

1

我会写的功能

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:mf="http://example.org/mf" 
    exclude-result-prefixes="xs mf"> 

<xsl:function name="mf:find_num" as="xs:integer*"> 
    <xsl:param name="input" as="xs:string"/> 
    <xsl:analyze-string select="$input" regex="[0-9]+"> 
    <xsl:matching-substring> 
     <xsl:sequence select="xs:integer(.)"/> 
    </xsl:matching-substring> 
    </xsl:analyze-string> 
</xsl:function> 

<xsl:template match="address"> 
    <xsl:value-of select="mf:find_num(.)" separator=", "/> 
</xsl:template> 

</xsl:stylesheet> 

当然转换为xs:integer是可选的,如果你想在函数返回的字符串包含数字序列只需将变化它做

<xsl:function name="mf:find_num" as="xs:string*"> 
    <xsl:param name="input" as="xs:string"/> 
    <xsl:analyze-string select="$input" regex="[0-9]+"> 
    <xsl:matching-substring> 
     <xsl:sequence select="."/> 
    </xsl:matching-substring> 
    </xsl:analyze-string> 
</xsl:function> 
+0

好吧,那很简单。不知道不需要非匹配子字符串。我可能会误解分析字符串函数。非常感谢,这正是我所寻找的:-) – 2013-05-08 14:24:01

+0

这当然可以做得更简单。 – 2013-05-08 14:45:04

2

无需复杂xsl:analyze-string处理的。

此XPath的一行

for $i in tokenize($pStr, '[^0-9]+')[.] 
    return xs:integer($i) 

产生整数想要的序列串在:

12 12345 

这是一个完整的转型

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="my:my"> 
<xsl:output method="text"/> 

<xsl:template match="/*"> 
    <xsl:sequence select="my:nums(.)"/> 
</xsl:template> 

<xsl:function name="my:nums" as="xs:integer*"> 
    <xsl:param name="pStr" as="xs:string"/> 

    <xsl:sequence select= 
    "for $i in tokenize($pStr, '[^0-9]+')[.] 
    return xs:integer($i)"/> 
</xsl:function> 
</xsl:stylesheet> 

当这种变换所提供的XML文档应用:

<address>street 12, 12345 town</address> 

想要的,正确的结果产生:

12 12345 

就更简单了,XPath的3.0一个-liner

tokenize($pStr, '[^0-9]+')[.] ! xs:integer(.) 
+0

谢谢你的回答,但我得到这个错误: 由于函数itp:find_num() – 2013-05-08 15:16:09

+0

@ChristianManthey不允许多个项目的序列,很可能你有一个复制/粘贴错误。请注意如何在答案中定义函数:'as =“xs:integer *”'。我的猜测是你已经省略了'as'属性,或者没有正确地重写它。 – 2013-05-08 15:39:55

+0

就是这样。我忘了*。好的解决方案谢谢! – 2013-05-08 15:55:38

相关问题