1

XSLT でカスタム生成された文字列シーケンスの一意の値を取得しようとしています。最初に「.」で文字列を分割する必要があるため、目前の問題はかなり珍しいものです。最後のビットをチョップします。これは正常に機能していますが、XSLT 2.0 の個別の値を使用して一意の値を取得することはできません。

いくつかの入力が与えられた場合

<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 の一部です)

また、一意性のためにキー付きインデックスまたはグループ化を使用しようとしましたが、それらはドキュメントのフラグメントではうまく機能しませんでした。

4

2 に答える 2

2

次の式は、文字列のシーケンスとして個別の値のセットを提供します。

distinct-values(TreeNumber/replace(., '\..*$', ''))
于 2012-11-26T22:26:40.447 に答える
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>
于 2012-11-26T21:50:12.803 に答える