これがまさにあなたが探しているものかどうかはわかりません (お願い: 入力と必要な出力 XML を常に含めることを忘れないでください)。しかし、追加の処理を適用する前に、空のノードと属性を再帰的に検索する汎用テンプレートがあります ( 「または」の後の部分を削除するだけで、属性チェックは必要ありません):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:i="whatever">
<xsl:output method="xml" indent="yes"/>
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="/*">
<xsl:copy>
<xsl:variable name="nil">
<xsl:apply-templates select="." mode="nil"/>
</xsl:variable>
<xsl:if test="$nil='true'">
<xsl:attribute name="i:nil">true</xsl:attribute>
</xsl:if>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="*" mode="nil">
<xsl:choose>
<xsl:when test="string-length(.)=0 or @*[string-length(.)=0]">
<xsl:value-of select="'true'"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*" mode="nil"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
nil の場合: 入力:
<TEST>
<Child test="aaa" secondtest="">asdf</Child>
</TEST>
出力:
<TEST xmlns:i="whatever" i:nil="true">
<Child test="aaa" secondtest="">asdf</Child>
</TEST>
nil なし: 入力 + 出力 (何もしない):
<TEST>
<Child test="aaa" secondtest="bbb">asdf</Child>
</TEST>