7 に答える
この変換では、ノードの子を持たない <b> 要素はすべて無視されます。このコンテキストでのノードは、要素、テキスト、コメント、または処理命令ノードを意味します。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes"/> <xsl:template match="node()|@*"> <xsl:コピー> <xsl:apply-templates select="node()|@*"/> </xsl:コピー> </xsl:テンプレート> <xsl:template match="b[not(node()]"/> </xsl:スタイルシート>
ここでは、最も基本的な XSLT 設計パターンの 1 つを使用していることに注意してください。恒等変換を使用し、特定のノードに対してそれをオーバーライドしています。
オーバーライド テンプレートは、"b" という名前の要素であり、子 (としてのノード) を持たないノードに対してのみ選択されます。このテンプレートは空 (コンテンツがない) であるため、その適用の効果は、一致するノードが無視/破棄され、出力で再現されないことです。
この手法は非常に強力で、このようなタスクや、名前の変更、内容や属性の変更、一致する特定のノードへの子や兄弟の追加などに広く使用されています (名前空間ノードを除くすべてのタイプのノードを使用できます)。 <xsl:template/> の「match」属性の一致パターンとして
これが役に立ったことを願っています。
乾杯、
ディミトレ・ノヴァチェフ
dsteinwegは私を正しい軌道に乗せました...私はやった:
<xsl:template match="b">
<xsl:if test="./* or ./text()">
<xsl:element name="b">
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
</xsl:template>
これでうまくいくのだろうか?
<xsl:template match="b">
<xsl:if test="b/text()">
...
別の方法として、次のようにします。
<xsl:template match="b[not(text())]" />
<xsl:template match="b">
<b>
<xsl:apply-templates/>
</b>
</xsl:template>
すべてのロジックを述語に入れ、必要なものだけに一致するようにテンプレートを設定して削除することができます。
<xsl:template match="b[not(node())] />
これは、トランスフォームの後で ID テンプレートがあることを前提としています。これにより、コンテンツを含む「b」タグが自動的にコピーされます。これが必要です。
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
編集:以下の Dimitri のように node() を使用するようになりました。
これが機能するかどうかを確認してください。
<xsl:template match="b">
<xsl:if test=".!=''">
<xsl:element name="b">
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
</xsl:template>
元の XML を更新するアクセス権がある場合は、ルート要素でuse xml:space=preserveを使用してみてください。
<html xml:space="preserve">
...
</html>
このようにして、空の <b> </b> タグのスペースが保持されるため、XSLT で <b /> と区別できます。
<xsl:template match="b">
<xsl:if test="text() != ''">
....
</xsl:if>
</xsl:template>