Опираясь на ответ @ Nic, вы можете использовать
<xsl:template match='br[preceding-sibling::node()[1][self::br]]'/>
Я только что изменил *
на node()
.Это решило бы проблему объединения двух <br/>
с текстом между ними.Однако он перестанет удалять дубликаты <br/>
s, даже если между ними будет только пробельный узел.
Чтобы решить это ...
Устаревший
Сначала я предположил, что вы можете убрать узлы только для пробелов из p
элементов во входном документе, поместив это на верхний уровень вашего XSLT:
<xsl:strip-space elements="p"/>
Но @Alejandro указал, что это может легко привести к потере важных пробелов , как в <p><em>bar</em> <em>baz</em></p>
.
Так что вместо этого
используйте этот измененный шаблон соответствия:
<xsl:template match='br[preceding-sibling::node()
[not(self::text() and normalize-space(.) = "")][1]
[self::br]]'/>
Вроде некрасиво, но должно работать.Это будет соответствовать и подавлять «любой br, для которого предыдущий узел-брат, который не является текстовым узлом только для пробелов, также является br».: -)
Учитывая, что шаблон соответствия настолько сложен, вы можете предпочесть перенести часть этой логики в тело шаблона следующим образом.Я предполагаю, что это больше вопрос личного вкуса и стиля:
<xsl:template match="br">
<xsl:if test="not(preceding-sibling::node()
[not(self::text() and normalize-space(.) = '')][1]
[self::br])">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:if>
</xsl:template>
Здесь мы используем копию преобразования идентичности, когда <br />
не тот, который мы хотим подавить.Я не думаю, что <br />
может принимать дочерние элементы или текст, но это не помешает быть безопасным.
( Обновил выше. Я забыл закончить этот пример кодав последний раз я сохранял правки.)