4

例として、次のような XML があります。

<root>
    <field1>test</field1>
    <f2>t2</f2>
    <f2>t3</f2>
</root>

XSLT で変換したいが、出力の 2 番目の f2 要素を抑制したい - ソースの 2 番目の f2 要素が処理されたときに、出力に f2 要素が既に存在するかどうかを確認するには、テンプレート内をどのように確認すればよいですか? 現在、私の XSLT は次のようになっています。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="no" omit-xml-declaration="yes" standalone="no" />
  <xsl:template match="/">
    <xsl:for-each select="./root">
      <output>
        <xsl:apply-templates />        
      </output>
    </xsl:for-each>
  </xsl:template>
  <xsl:template match="*" >
      <xsl:element name="{name(.)}">
        <xsl:value-of select="." />
      </xsl:element>
  </xsl:template>
</xsl:stylesheet>

テンプレートの xsl:element について何らかのチェックを行う必要があると思いますが、出力ドキュメントを調べて、要素が既に存在するかどうかを確認する方法がわかりません。

編集: pre タグを忘れました。コードが表示されるはずです!

4

3 に答える 3

7

それはあなたがどれだけシステム全体になりたいかによります。

つまり、同じ親の子である要素、または同じレベルのすべての要素(必要に応じて「いとこ」)、またはドキュメント内の任意の要素のみに関心がありますか。

最初の状況では、前の兄弟軸をチェックして、同じ名前の他の要素が存在するかどうかを確認できます。

<xsl:if test="count(preceding-sibling::node()[name()=name(current())])=0">
  ... do stuff in here.
</xsl:if>
于 2008-10-01T15:12:33.987 に答える
1

変換の出力を調べることはできません。また、トランスフォームの現在の状態を追跡することもできません (つまり、変数でどのノードを発行したかを追跡します)。基本的に、それは XSLT の仕組みではありません。副作用のないプログラミング環境のコストの 1 つは、副作用のあることを実行できないことです。しかたがない。

あなたの場合、これを達成する1つの方法は、一度だけ出力したい出力要素に変換できるすべてのソース要素のリストを含む変数を作成することです。次に、このリストに対して変換するすべてのノードを確認します。リストにない場合は、発行します。それがリストの最初の項目である場合は、それを発行します。そうでなければ、しないでください。

于 2008-10-02T00:34:06.040 に答える
1

チェックのみ(および重複を警告)するには、ここに例を見つけることができます

次のようなもの:

<xsl:for-each-group select="collection(...)//@id" group-by=".">
  <xsl:if test="count(current-group()) ne 1">
    <xsl:message>Id value <xsl:value-of select="current-grouping-key()"/> is 
       duplicated in files
       <xsl:value-of select="current-group()/document-uri(/)" separator=" and
    "/></xsl:message>
  </xsl:if>
 </xsl:for-each-group>

「ルート」要素内のすべてのノードを選択するように変更します。

重複行を削除するには、ここに別の例があります

それは次のようになります。

<xsl:stylesheet>
  <xsl:key name="xyz" match="record[x/y/z]" use="x/y/z" />
  <xsl:variable name="noxyzdups" select="/path/to/record[generate-id(.) = generate-id(key('xyz', x/y/z))]" />
...
  <xsl:template ... >
    <xsl:copy-of "exslt:node-set($noxyzdups)" />
  </xsl:template>
</xsl:stylesheet>

x/y/z は、一意にする xpath 式です。concat(x,'-',@y,'-',z) または任意のものにすることができます。

これら2つの例があなたのケースに簡単に適応できるかどうかはわかりませんが、役立つ場合に備えて、これら2つのソースを指摘したかっただけです.

于 2008-10-01T15:38:55.110 に答える