質問
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タグを忘れた場合、コードが表示されるはずです!
解決
システム全体の幅に依存します。
i.e。同じ親の子である要素、または同じレベルのすべての要素(必要に応じて「いとこ」)またはドキュメント内の任意の要素のみに関心がありますか...
最初の状況では、前の兄弟軸をチェックして、同じ名前の他の要素が存在するかどうかを確認できます。
<xsl:if test="count(preceding-sibling::node()[name()=name(current())])=0">
... do stuff in here.
</xsl:if>
他のヒント
チェック(および重複の警告)のみを行うには、例はこちら
次の行に沿ったもの:
<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>
「root」要素内のすべてのノードを選択するように変更する。
重複行を削除するために、別のの例がありますここ
次のようになります:
<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つのソースを指摘したいだけです。
変換の出力を調べることはできません。トランスフォームの現在の状態を追跡することもできません(つまり、変数でどのノードを発行したかを追跡します)。基本的に、それはXSLTの仕組みではありません。副作用のないプログラミング環境のコストの1つは、副作用のあることを実行できないことです。まあ。
これを実現する1つの方法は、一度だけ出力したい出力要素に変換できるすべてのソース要素のリストを含む変数を作成することです。次に、このリストに対して変換するすべてのノードを確認します。リストにない場合は、送信します。リストの最初のアイテムである場合、それを発行します。それ以外の場合は、しないでください。