2015-01-29 1 views
-3

Мне нужно проверить, содержит ли элемент el текст с форматом 1.1.1. Как определить этот элемент?XSLT выберите элемент с текстом, содержащим номер в формате «1.1.1»

<root> 
    <story> 
    <el>1.1.1 <b>head1</b></el> 
    <el>some text</el> 
    <el>1.1.1 <b>head1</b></el> 
    <el>some text</el> 
    <el>1.10.2<b>head1</b></el> 
    <el>some text</el> 
    <el>19.9.10<b>head1</b></el> 
</story> 
</root> 

Любая помощь будет оценена по достоинству. Ну, я надеюсь, следующий результат:

<root> 
    <story> 
    <h3>1.1.1 head1</h3> 
    <el>some text</el> 
    <h3>1.1.1 head1</h3> 
    <el>some text</el> 
    <h3>1.10.2 head1</h3> 
    <el>some text</el> 
    <h3>19.9.10 head1</h3> 
    </story> 
</root> 
+0

Вы пытались что-нибудь еще? Существует несколько методов, которые будут работать. – Gusdor

+0

К сожалению, я этого не сделал. – sprut

+0

Какую версию XSLT вы используете? Варианты 1 и 2 потенциально могут иметь разные ответы? –

ответ

0

Вы действительно должны пробовали что-то. В таких проблемах, где вы только трансформируете часть 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+$')]"> 
+0

Отлично! Большое вам спасибо, Тим). Ты сэкономил мне много времени. – sprut

+0

Принимается за право – sprut

Смежные вопросы