2013-05-08 68 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

相關問題