2016-03-07 43 views
1

我有一個XML片段是這樣的:XSLT +正則表達式替換

... 
<housenumber>23</housenumber> 
... 
<housenumber>453a</housenumber> 
... 
<housenumber>76-79</housenumber> 
... 
<housenumber>12 foo bar something 43</housenumber> 
... 

我怎麼能砍這些housenumbers分爲兩個部分使用XSLT讓我得到兩個變量 - 第一個含「一切從位置1到第一次出現一個非數字字符「,第二個包含」其他「?

因此,像這樣:

... 
<housenumber>23</housenumber> 
<!-- v1 = 23, v2 = null --> 
... 
<housenumber>453a</housenumber> 
<!-- v1 = 453, v2 = a --> 
... 
<housenumber>76-79</housenumber> 
<!-- v1 = 76, v2 = -79 --> 
... 
<housenumber>12 foo bar something 43</housenumber> 
<!-- v1 = 12, v2 = foo bar something 43 --> 
... 

任何提示/想法?

謝謝。

+1

正則表達式匹配需要XSLT 2.0。在你的情況'分析字符串'可能會適合。 – zx485

+1

您需要說明您是否可以使用XSLT 2.0或是否使用XSLT 1.0。 –

+0

@MichaelKay:目前檢查此...請支持:-) – tschlein

回答

2

正如評論所指出的,analyze-string能有所幫助,這裏是使用XSLT 3.0爲例,這使得使用XPath 3.0功能analyze-stringhttps://www.w3.org/TR/xpath-functions-30/#func-analyze-string

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:fn="http://www.w3.org/2005/xpath-functions" 
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
    exclude-result-prefixes="xs math fn" 
    version="3.0"> 

    <xsl:template match="root"> 
     <xsl:variable name="matches" select="housenumber/analyze-string(., '(^[0-9]+)([^0-9]?.*)')//fn:match"/> 
     <xsl:variable name="v1" select="$matches//fn:group[@nr = 1]/xs:integer(.)"/> 
     <xsl:variable name="v2" select="$matches//fn:group[@nr = 2]/string()"/> 
     <integers> 
      <xsl:value-of select="$v1" separator=","/> 
     </integers> 
     <strings> 
      <xsl:value-of select="$v2" separator=","/> 
     </strings> 
    </xsl:template> 
</xsl:stylesheet> 
(由撒克遜9.7或Exselt的支持)

與樣品

<root> 
    <housenumber>23</housenumber> 
    ... 
    <housenumber>453a</housenumber> 
    ... 
    <housenumber>76-79</housenumber> 
    ... 
    <housenumber>12 foo bar something 43</housenumber> 
</root> 

我得到的輸出

<integers>23,453,76,12</integers><strings>,a,-79, foo bar something 43</strings> 

使用XSLT 2.0,你可以使用xsl:analyze-string指令:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    version="2.0"> 

    <xsl:template match="root"> 
     <xsl:variable name="matches" as="element(match)*"> 
      <xsl:apply-templates select="housenumber"/> 
     </xsl:variable> 
     <xsl:variable name="v1" select="$matches//group[@nr = 1]/xs:integer(.)"/> 
     <xsl:variable name="v2" select="$matches//group[@nr = 2]/string()"/> 
     <integers> 
      <xsl:value-of select="$v1" separator=","/> 
     </integers> 
     <strings> 
      <xsl:value-of select="$v2" separator=","/> 
     </strings> 
    </xsl:template> 

    <xsl:template match="housenumber"> 
     <xsl:analyze-string select="." regex="(^[0-9]+)([^0-9]?.*)"> 
      <xsl:matching-substring> 
       <match> 
        <group nr="1"> 
         <xsl:value-of select="regex-group(1)"/> 
        </group> 
        <group nr="2"> 
         <xsl:value-of select="regex-group(2)"/> 
        </group> 
       </match> 
      </xsl:matching-substring> 
     </xsl:analyze-string> 
    </xsl:template> 

</xsl:stylesheet>