Вы действительно должны пробовали что-то. В таких проблемах, где вы только трансформируете часть XML (в вашем случае, изменяя el
на h3
и удаляя b
), вы должны сразу подумать «Ага! Идентичность» (см. http://en.wikipedia.org/wiki/Identity_transform). Это означает, что начинать с этого шаблона
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
Тогда вы на полпути! Затем вам нужно только написать шаблоны, чтобы изменить нужные вам узлы (которые должны иметь приоритет над шаблоном общего идентификатора).
Теперь, когда вы используете XSLT 1.0, нет никакого способа идентифицировать «число» в формате 1.1.1. Если вы хотите радоваться запутанным выражениям, вот один из способов сопоставления ваших элементов el
, который затем заменяется на элемент h3
.
<xsl:template match="el[normalize-space(concat('[', translate(translate(normalize-space(text()), ' ', '_'), '1234567890', ' '), ']')) = '[ . . ]']">
<h3>
<xsl:apply-templates select="@*|node()"/>
</h3>
</xsl:template>
Вы бы иметь такие же один для сопоставления, а затем удаления, в b
элемент под el
<xsl:template match="el[normalize-space(concat('[', translate(translate(normalize-space(text()), ' ', '_'), '1234567890', ' '), ']')) = '[ . . ]']/b">
<xsl:text> </xsl:text>
<xsl:apply-templates />
</xsl:template>
Тем не менее, это будет означать кодирования ужасного выражения в два раз, так что альтернативный подход может быть использовать атрибут mode
при вызове шаблона.
Попробуйте этот XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="el[normalize-space(concat('[', translate(translate(normalize-space(text()), ' ', '_'), '1234567890', ' '), ']')) = '[ . . ]']">
<h3>
<xsl:apply-templates select="@*|node()" mode="b"/>
</h3>
</xsl:template>
<xsl:template match="b" mode="b">
<xsl:text> </xsl:text>
<xsl:apply-templates />
</xsl:template>
<xsl:template match="@*|node()" mode="b">
<xsl:call-template name="identity" />
</xsl:template>
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Обратите внимание, что в XSLT 2.0, вы можете использовать функцию matches
<xsl:template match="el[matches(normalize-space(text()), '^\d+\.\d+\.\d+$')]">
Вы пытались что-нибудь еще? Существует несколько методов, которые будут работать. – Gusdor
К сожалению, я этого не сделал. – sprut
Какую версию XSLT вы используете? Варианты 1 и 2 потенциально могут иметь разные ответы? –