Как скопировать все дочерние узлы любого типа элемента контекста шаблона

Я преобразовываю XML в HTML с помощью XSLT.

У меня есть следующая структура XML:

<root>
    <element>
        <subelement>
            This is some html text which should be <span class="highlight">displayed highlighted</span>.
         </subelement>
    </element>
</root>

Я использую следующий шаблон для преобразования:

<xsl:template name="subelement">
  <xsl:value-of select="." />
</xsl:template>

К сожалению, я теряю <span> -tags.

Есть ли способ сохранить их, чтобы HTML отображался правильно (выделено)?

Ответ 1

Правильный способ получить все содержимое текущего соответствия node (включая текстовые узлы):

    <xsl:template match="subelement">
       <xsl:copy-of select="node()"/>
    </xsl:template>

Это скопирует все потомки.

Ответ 2

Попробуйте использовать <xsl:copy-of... вместо <xsl:value-of..., например:

<xsl:template name="subelement">
  <xsl:copy-of select="*" />
</xsl:template>

Обратите внимание на *, который остановит биты <subelement></subelement>, выводимые на результаты, вместо использования ., которые будут содержать биты <subelement></subelement>.

Например, таблица стилей xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:template match="root/element">
        <output>
            <xsl:apply-templates select="subelement"/>
        </output>
    </xsl:template>

    <xsl:template match="subelement">
        <xsl:copy-of select="*"/>
    </xsl:template>

</xsl:stylesheet>

когда применяется к вашему примеру xml файл:

<?xml version="1.0" encoding="UTF-8"?>
<output>
    <span class="highlight">displayed highlighted</span>
</output>

Ответ 3

Объявление <xsl:value-of> принимает конкатенированное содержимое всех текстовых узлов внутри элемента в последовательном порядке и не выводит никаких элементов вообще.

Вместо этого я рекомендую использовать <xsl:apply-templates>. Где он найдет текст node, он выведет содержимое как есть, но вам нужно будет определить шаблон для обработки тегов span, чтобы преобразовать их в html. Если этот тег span является html-тегом, то, строго говоря, у вас должно быть отдельное пространство имен для вашей собственной структуры документа и html.