XSLT применяет шаблоны и манипулирует строками
У меня есть некоторые XML, как так:
<subsection number="5">
<p>
(5) The <link path="123">Secretary of State</link> shall appoint such as....
</p>
</subsection>
Я не могу изменить XML, и мне нужно вычеркнуть (5) в начале абзаца и использовать атрибут номера в родительском теге, чтобы создать новый номер абзаца с соответствующей разметкой:
<xsl:template match="subsection/p">
<xsl:variable name="number">
<xsl:text>(</xsl:text>
<xsl:value-of select="../@number"/>
<xsl:text>)</xsl:text>
</xsl:variable>
<xsl:variable name="copy">
<xsl:value-of select="."/>
</xsl:variable>
<p>
<span class="indent">
<xsl:value-of select="$number" />
</span>
<span class="copy">
<xsl:value-of select="substring-after($copy, $number)" />
</span>
</p>
</xsl:template>
Проблема в том, что остальная часть абзаца может содержать больше XML, который необходимо преобразовать, например, тег ссылки в примере.
Я не знаю, как применить шаблоны к этому, как только я использовал функцию substring-after.
1 ответ
Решение
Явный подход заключается в обработке первого текстового потомка subsection/p
элементы отдельно от всех других детей. Для демонстрации я также добавил шаблон для конвертации link
элементы в a
элементы.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="subsection/p/text()[1]">
<xsl:value-of select="concat('(', ../../@number, ')')"/>
</xsl:template>
<xsl:template match="subsection/p">
<p>
<span class="indent">
<xsl:apply-templates select="text()[1]"/>
</span>
<span class="copy">
<xsl:apply-templates select="*|text()[not(position()=1)]"/>
</span>
</p>
</xsl:template>
<xsl:template match="subsection/p/link">
<a href="{@path}"><xsl:value-of select="."/></a>
</xsl:template>
</xsl:stylesheet>
Эта таблица стилей производит следующий вывод:
<p><span class="indent">(5)</span><span class="copy">
<a href="123">Secretary of State</a>shall appoint such as....</span></p>