1

xslt-stylesheet では、メソッドexsl:node-setset:distinctを使用して、結果ツリー フラグメントを含む変数から一意のノードにアクセスしてフィルター処理しています。これらのノードの値を出力ファイルに書き込むことができます。例:

<xsl:variable name="myNodes">
  <xsl:call-template name="getNodes"/>
</xsl:variable>

<xsl:for-each select="set:distinct(exsl:node-set($myNodes)/key)">
  <xsl:value-of select="."/>
</xsl:for-each>

予想どおり、キーの値が出力に書き込まれます。ただし、XPath 式で値を使用しようとすると、失敗します。

<xsl:for-each select="set:distinct(exsl:node-set($myNodes)/key)">
  <xsl:variable name="result" select="/tree//somenode[@key = current()]"/>
  <xsl:value-of select="$result"/>
</xsl:for-each>

現在、出力は空ですが、input-xml に XPath 式で選択する必要がある「somenode」があり、その値が空ではないことがわかっています。

今私の質問は:なぜこれが起こるのですか?

Java 1.6、Xerces 2.7、および Xalan 2.7 を使用しています。

更新: 要求に応じて、例の一部のデータ: xml doc には以下が含まれます。

<tree>
  <somenode key="123"/>
  <num>123</num>
  <num>0815</num>
</tree>

getNodes テンプレート:

<xsl:template name="getNodes">
  <xsl:for-each select="/tree/num">
    <xsl:element name="key">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:for-each>
</xsl:template>
4

2 に答える 2

3

これは、あなたが望むものに近い何かを行う変換です:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:set="http://exslt.org/sets"
 xmlns:exsl="http://exslt.org/common"
 >
 <xsl:output omit-xml-declaration="yes"/>

 <xsl:template match="/">
  <xsl:variable name="myNodes">
    <xsl:call-template name="getNodes"/>
  </xsl:variable>


  <xsl:variable name="vDoc" select="/"/>

  <xsl:for-each select="set:distinct(exsl:node-set($myNodes)/key)">
    <xsl:variable name="result" select="$vDoc/tree//somenode[@key = current()]"/>
    <xsl:copy-of select="$result"/>
  </xsl:for-each>
 </xsl:template>

 <xsl:template name="getNodes">
  <xsl:for-each select="/tree/num">
    <xsl:element name="key">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントに適用した場合:

<tree>
  <somenode key="123"/>
  <num>123</num>
  <num>0815</num>
</tree>

必要な結果が生成されます:

<somenode key="123"/>

注意してください:

  1. <xsl:for-each>この命令は、現在のノードを別のドキュメント ( によって作成された一時ツリー) 内のノードに設定するため、 内ソース XML ドキュメントに直接アクセスすることはできませんexsl:node-set()

  2. このため、ソース XML ドキュメントを変数にキャプチャします$vDoc<xsl:for-each>この変数を介して、内部のソース XML ドキュメントにアクセスします。

  3. 要素<somenode key="123"/>にはテキストノードの子孫がないため、文字列値がありません。onを使用<xsl:value-of>しても出力は生成されません。これが、<xsl:copy-of>ここで使用する理由です。完全な要素がコピーされ、結果が表示されます。

于 2010-08-26T12:51:36.997 に答える
0

このスタイルシートは、拡張機能なしで必要なことを実行します。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="NumByValue" match="num" use="."/>
    <xsl:template match="num[count(.|key('NumByValue',.)[1])=1]">
        <xsl:copy-of select="../somenode[@key=current()]"/>
    </xsl:template>
</xsl:stylesheet>

出力:

<somenode key="123" />
于 2010-08-26T13:22:33.537 に答える