2017-08-16 3 views
0

述語内でgenerate-id()関数を使用して、以前に生成されたIDと比較しています。しかし、これはうまくいかず、理由を理解できません。述語内のXSLT generate-id()が機能しません。

私は、入力と期待される出力を持つサンプルXSLTを作成しました。はい、私は知っています - このコードは奇妙に見えますが、理にかなっていません。なぜそれが見つからないのですか?generate-id()はここでは動作しません。

問題行は以下の通りです:

<xsl:value-of select="a[generate-id(current())=$a_id]/text()"/> 

これは動作しません。ここでは、完全なXML入力、XSLT、および期待される出力を示します。

XML入力:

<root> 
    <test> 
     <a>1</a> 
     <a>2</a> 
     <a>3</a> 
    </test> 
</root> 

予想される出力:

<root> 
    <test> 
     <a>1</a> 
    </test> 
    <test> 
     <a>2</a> 
    </test> 
    <test> 
     <a>3</a> 
    </test> 
</root> 

結果の出力(値はID検索で見つからない):ここでは

<root> 
    <test> 
     <a/> 
    </test> 
    <test> 
     <a/> 
    </test> 
    <test> 
     <a/> 
    </test> 
</root> 

はXSLTです。 ...あなたの質問への答えはあなたがこれを行う必要があるということです

<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:output indent="yes"></xsl:output>  

    <xsl:template match="/root"> 
     <xsl:copy> 
      <xsl:apply-templates select="test"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="test"> 
     <xsl:for-each select="a"> 
      <xsl:apply-templates select=".." mode="output"> 
       <xsl:with-param name="a_id" select="generate-id()"/> 
      </xsl:apply-templates> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="test" mode="output"> 
     <xsl:param name="a_id"/> 
     <xsl:copy> 
      <xsl:element name="a"> 
       <!-- Here the passed a_id cannot be found --> 
       <xsl:value-of select="a[generate-id(current())=$a_id]/text()"/> 
      </xsl:element>    
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

答えて

1

..この代わりとして、あなたのXSLTを再度書くことができますidはa要素のものであり、test要素のものはa要素ではありません。 XSLT 2.0にはisという演算子があるので、IDを渡したり比較したりする必要はなく、要素を直接渡して出力することも、IDに基づいていくつかのノードを比較する必要がある場合は、そのisオペレータ。

+0

'is'演算子でヒントを作成します。素晴らしい作品です。これ以上generate-id()を使用しないでください。ありがとう – FiveO

1

<xsl:value-of select="a[generate-id(.)=$a_id]/text()"/> 

あるいはこの...

<xsl:value-of select="a[generate-id()=$a_id]/text()"/> 

:問題は、最後のテンプレートでありますcurrent()は一致する現在のノードを指し、testノードです。 .は、現在のコンテキスト(aノード)を参照します。詳細は、Current node vs. Context node in XSLT/XPath?を参照してください。

もう一つの答えは、複雑すぎることがあるかもしれないということです。あなたはtestはので、私はあなたが単にあなたが比較を確認する

a[generate-id(.)=$a_id] 

をしたいと思うマッチしたあなたのtemplate match="test"current()機能の選択の内部

<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:output indent="yes"></xsl:output>  

    <xsl:template match="/root"> 
     <xsl:copy> 
      <xsl:apply-templates select="test"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="test"> 
     <xsl:for-each select="a"> 
      <test> 
       <xsl:apply-templates select="." /> 
      </test> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 
関連する問題