Есть ваше решение:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@* | text()">
<xsl:copy />
</xsl:template>
<xsl:template match="table | tr | td">
<!-- result of the transformation of descendants -->
<xsl:variable name="content">
<xsl:apply-templates select="node()" />
</xsl:variable>
<!-- if there are any children left then copy myself -->
<xsl:if test="count($content/node()) > 0">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:copy-of select="$content" />
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Идея проста. Сначала я сделаю преобразование для своих потомков, а затем посмотрю, есть ли еще кто-нибудь. Если это так, я буду копировать себя и результат преобразования.
Если вы хотите сохранить структуру таблицы и удалить только пустые строки - элементы <tr>
, содержащие только пустые элементы <td>
, чем просто создать аналогичный шаблон для <tr>
с другим условием и игнорировать элементы <td>
.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@* | text()">
<xsl:copy />
</xsl:template>
<xsl:template match="table">
<!-- result of the transformation of descendants -->
<xsl:variable name="content">
<xsl:apply-templates select="node()" />
</xsl:variable>
<!-- if there are any children left then copy myself -->
<xsl:if test="count($content/node()) > 0">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:copy-of select="$content" />
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="tr">
<!-- result of the transformation of descendants -->
<xsl:variable name="content">
<xsl:apply-templates select="node()" />
</xsl:variable>
<!-- number of non-empty td elements -->
<xsl:variable name="cellCount">
<xsl:value-of select="count($content/td[node()])" />
</xsl:variable>
<!-- number of other elements -->
<xsl:variable name="elementCount">
<xsl:value-of select="count($content/node()[name() != 'td'])" />
</xsl:variable>
<xsl:if test="$cellCount > 0 or $elementCount > 0">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:copy-of select="$content" />
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Ну, на самом деле последний if
должен быть таким:
<xsl:choose>
<!-- if there are cells then copy the content -->
<xsl:when test="$cellCount > 0">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:copy-of select="$content" />
</xsl:copy>
</xsl:when>
<!-- if there are only other elements copy them -->
<xsl:when test="$elementCount > 0">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:copy-of select="$content/node()[name() != 'td']" />
</xsl:copy>
</xsl:when>
</xsl:choose>
Это происходит из-за ситуации, когда <tr>
содержит пустые элементы <td>
и другие элементы. Затем вы хотите удалить <td>
s и оставить только остальные.