2012-11-26 30 views
0

我想要獲取XSLT中字符串的自定義生成序列的唯一值。 由於我必須首先在'。'上分割一個字符串,因此手頭的問題相當不尋常。和最後一位的印章,這工作正常,但使用XSLT 2.0不同值獲取唯一值不是。使用XSLT函數從序列中獲取不同值

鑑於一些輸入

<TreeNumberList> 
    <TreeNumber>A01.001.001</TreeNumber> 
    <TreeNumber>A01.001.002</TreeNumber> 
    <TreeNumber>A01.001.003</TreeNumber> 
    <TreeNumber>A01.002.111</TreeNumber> 
</TreeNumberList> 

所需的輸出將是

A01.001, A01.002 

可迭代序列到目前爲止,我有以下功能

<xsl:function name="func:strip-last"> 
    <xsl:param name="str"></xsl:param> 
    <xsl:value-of select="substring($str, 1, string-length($str) - 1)"></xsl:value-of> 
</xsl:function> 

<xsl:function name="func:parent-of"> 
    <xsl:param name="nodes"></xsl:param> 
    <xsl:variable name="output"> 
    <xsl:for-each select="$nodes"> 
     <xsl:variable name="parent"> 
      <xsl:for-each select="tokenize(., '\.')"> 
       <xsl:if test="position() != last()"> 
        <xsl:value-of select="."></xsl:value-of> 
        <xsl:text>.</xsl:text> 
       </xsl:if> 
      </xsl:for-each> 
     </xsl:variable> 
     <tmp><xsl:value-of select="func:strip-last($parent))"></xsl:value-of></tmp> 
    </xsl:for-each>  
    </xsl:variable> 
    <xsl:sequence select="distinct-values($output/*)"></xsl:sequence> 
</xsl:function> 

但這並不返回一組不同的元素,而是一系列涉及的所有元素。最終的代碼會更有意思,因爲TreeNumbers本身不會是唯一的,但是通過密鑰查找將獲取某個名稱。 (對於那些識別標記,它是MeSH XML的一部分)

我也嘗試過使用key-ed索引或group-by來獲得唯一性,但那些文檔片段沒有很好地發揮作用。

回答

1

下面的表達式給出了一套不同的值作爲字符串的序列:

distinct-values(TreeNumber/replace(., '\..*$', '')) 
+1

不錯!這比'xsl:analyze-string'容易得多。我總是忘記'replace()'。 +1 –

1

你必須有功能嗎?你可以創建一個具有序列的變量嗎?

實施例...

XML輸入

<TreeNumberList> 
    <TreeNumber>A01.001.001</TreeNumber> 
    <TreeNumber>A01.001.002</TreeNumber> 
    <TreeNumber>A01.001.003</TreeNumber> 
    <TreeNumber>A01.002.111</TreeNumber> 
</TreeNumberList> 

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:variable name="vAllTreeNumbers"> 
     <xsl:for-each select="/*/TreeNumber"> 
      <xsl:analyze-string select="." regex="(.*)\.[^.]*$"> 
       <xsl:matching-substring> 
        <xsl:value-of select="concat(regex-group(1),' ')"/> 
       </xsl:matching-substring> 
      </xsl:analyze-string> 
     </xsl:for-each> 
    </xsl:variable> 
    <xsl:variable name="vUniqueTreeNumbers" select="distinct-values(tokenize(normalize-space($vAllTreeNumbers),' '))"/> 

    <xsl:template match="/"> 
     <results> 
      <!--This demonstrates that each value is part of a sequence.--> 
      <xsl:for-each select="$vUniqueTreeNumbers"> 
       <item> 
        <xsl:value-of select="."/> 
       </item> 
      </xsl:for-each> 
     </results> 
    </xsl:template> 

</xsl:stylesheet> 

XML輸出(只是爲了演示的序列)

<results> 
    <item>A01.001</item> 
    <item>A01.002</item> 
</results> 

下面是返回相同的結果的另一種選擇...

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:local="local" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:function name="local:getUniqueTreeNumbers"> 
     <xsl:param name="pNodes"/> 
     <xsl:variable name="vAllTreeNumbers"> 
      <xsl:for-each select="$pNodes"> 
       <xsl:analyze-string select="." regex="(.*)\.[^.]*$"> 
        <xsl:matching-substring> 
         <xsl:value-of select="concat(regex-group(1),' ')"/> 
        </xsl:matching-substring> 
       </xsl:analyze-string> 
      </xsl:for-each> 
     </xsl:variable> 
     <xsl:sequence select="distinct-values(tokenize(normalize-space($vAllTreeNumbers),' '))"></xsl:sequence> 
    </xsl:function> 

    <xsl:template match="/"> 
     <results> 
      <!--This demonstrates that each value is part of an iterable sequence.--> 
      <xsl:for-each select="local:getUniqueTreeNumbers(*/TreeNumber)"> 
       <item> 
        <xsl:value-of select="."/> 
       </item> 
      </xsl:for-each>   
     </results> 
    </xsl:template> 

</xsl:stylesheet>