2016-01-15 55 views
0

位數我有這樣的XML,XSLT - 正則表達式只選擇一個從文本()節點

<section> 
    <para>height 4cm, width 5cm, weight 343</para> 
    <para>height 2cm, width 6cm, weight 410</para> 
    <para>height 3cm, width 1cm, weight 590</para> 
</section> 

這裏我需要加倍para/text()的單個數字。所需的輸出應該看起來像,

<section> 
     <para>height 8cm, width 10cm, weight 343</para> 
     <para>height 4cm, width 12cm, weight 410</para> 
     <para>height 6cm, width 2cm, weight 590</para> 
    </section> 

要做到這一點我有這樣的一個模板,

<xsl:template match="para/text()"> 
     <xsl:analyze-string select="." regex="\d"> 

      <xsl:matching-substring> 
       <xsl:value-of select="2 * number(.)"/> 
      </xsl:matching-substring> 

      <xsl:non-matching-substring> 
       <xsl:value-of select="."/> 
      </xsl:non-matching-substring> 

     </xsl:analyze-string> 
    </xsl:template> 

這裏的問題是一個雙本,這需要無一位數字爲一位數他們,

電流輸出,

<section> 
    <para>height 8cm, width 10cm, weight 686</para> 
    <para>height 4cm, width 12cm, weight 820</para> 
    <para>height 6cm, width 2cm, weight 10180</para> 
</section> 

任何建議,我怎麼能解決這個問題?

+1

您可以使用'「\ b \ d \ b」'來匹配單個數字的整數。但是,這不會考慮上下文(您可能有興趣更改所有'cm'單元值 - 然後使用'\ d + cm'表達式在下面使用答案)。 –

+0

@stribizhev我不確定'\ b'在XSLT中是否被允許,我得到:'正則表達式中的錯誤:net.sf.saxon.trans.XPathException:在 處的語法錯誤正則表達式中的字符2:轉義字符'b '不允許'。 –

+0

@MathiasMüller:你說得對。我在官方文檔中查找,但是在這裏找到:) [如何使用XSLT 2在文本中查找單詞。0和REGEX(它沒有\ b字邊界)?](http://stackoverflow.com/questions/2397574/how-to-find-a-word-within-text-using-xslt-2-0 -and-正則表達式-其中-犯規具備的,體重)。不過,如果你打算在'cm'之前匹配數字,你不需要限制爲只有一位數。 –

回答

2

如果定義了一個「單位數」爲一個單一的數字非數字字符包圍,然後你可以使用:

<xsl:template match="para/text()"> 
    <xsl:analyze-string select="." regex="(\D)(\d)(\D)"> 

    <xsl:matching-substring> 
     <xsl:value-of select="regex-group(1)"/> 
     <xsl:value-of select="2 * number(regex-group(2))"/> 
     <xsl:value-of select="regex-group(3)"/> 
    </xsl:matching-substring> 

    <xsl:non-matching-substring> 
     <xsl:value-of select="."/> 
    </xsl:non-matching-substring> 

    </xsl:analyze-string> 
</xsl:template> 

請注意,這並不是一開始捕獲單位數或在字符串的末尾。要包含這些內容,您必須使用:

<xsl:analyze-string select="." regex="(^|\D)(\d)(\D|$)"> 
4

有幾種方法可以解決這個問題。一種方法是要求單個數字後跟「cm」(如果輸入XML中始終存在這種情況,那麼我們還不知道)。

XSLT樣式表

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" /> 

    <xsl:template match="para/text()"> 
     <xsl:analyze-string select="." regex="\dcm"> 

      <xsl:matching-substring> 
       <xsl:value-of select="2 * number(substring-before(.,'cm'))"/> 
      </xsl:matching-substring> 

      <xsl:non-matching-substring> 
       <xsl:value-of select="."/> 
      </xsl:non-matching-substring> 

     </xsl:analyze-string> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:transform> 

XML輸出

<section> 
    <para>height 8, width 10, weight 343</para> 
    <para>height 4, width 12, weight 410</para> 
    <para>height 6, width 2, weight 590</para> 
</section> 

或者,你可以如需要將單個數字後面的東西是不是一個數字:

<xsl:template match="para/text()"> 
    <xsl:analyze-string select="." regex="\d[^\d]"> 

     <xsl:matching-substring> 
      <xsl:value-of select="2 * number(substring(.,1,1))"/> 
     </xsl:matching-substring> 

     <xsl:non-matching-substring> 
      <xsl:value-of select="."/> 
     </xsl:non-matching-substring> 

    </xsl:analyze-string> 
</xsl:template> 

如果總是適用於你的數據,因爲它不包括那裏是一個字符串的最後一個數字的情況。


要考慮所有可能的情況下,使用

<xsl:template match="para/text()"> 
    <xsl:analyze-string select="." regex="(^|[^\d])(\d)([^\d]|$)"> 

     <xsl:matching-substring> 
      <xsl:value-of select="regex-group(1)"/> 
      <xsl:value-of select="2 * number(regex-group(2))"/> 
      <xsl:value-of select="regex-group(3)"/> 
     </xsl:matching-substring> 

     <xsl:non-matching-substring> 
      <xsl:value-of select="."/> 
     </xsl:non-matching-substring> 

    </xsl:analyze-string> 
</xsl:template> 

基本上是一樣的michael.hor257k曾建議(我先!)。

+0

你有兩個問題:(1)你丟棄了下面的非數字字符,把1cm變成2m; (2)你正在處理多位數字的最後一位數字 - 將'111kg'變成'112g'。 –

+0

@ michael.hor257k感謝您的評論,我現在修正了第一個問題 - 查看第二個問題。 –

+0

您已修正(1),但未修正(2)。 –