Преобразовать атрибут в закомментированный XML

Я хочу преобразовать комментарий, который я знаю, является действительным XML. Например, ниже я хочу изменить значение атрибута bar с x на y.

<root><!-- <foo bar="x"/> --></root>

Таблица стилей, которую я создал ниже

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exslt="http://exslt.org/common">

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="comment()">
        <xsl:comment>
            <xsl:variable name="xml-string">
                <xsl:value-of select="current()" />
            </xsl:variable>
            <xsl:variable name="xml-node" select="exslt:node-set($xml-string)" />
            <xsl:apply-templates select="$xml-node" />
        </xsl:comment>
    </xsl:template>

    <xsl:template match="@bar[parent::foo]">
        <xsl:attribute name="bar">
            <xsl:value-of select="'y'" />
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

но вывод, который я получаю из этого

<?xml version="1.0" encoding="UTF-8"?><root><!-- <foo bar="x"/> --></root>

Я подозреваю, что функция набора узлов на самом деле не делает то, что я думал, что будет.

Любая помощь будет очень высоко ценится.

2 ответа

Чтобы сделать это в XSLT 1.0 или 2.0, без каких-либо функций расширения, вам придется сделать это в два этапа:

Сначала примените следующую таблицу стилей к вашему входному XML:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="comment()">
    <xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>

</xsl:stylesheet>

и сохраните результат в файл. Затем обработайте полученный файл вторым XSLT.

Обратите внимание, что не все процессоры поддерживают disable-output-escaping,


Добавлено:

Надо сказать, что тебя отправили сюда по глупому поручению. После того, как вы закомментировали XML, он больше не является XML и не может быть обработан как таковой без каких-либо серьезных скачков через обручи.

Точно так же, если вы ожидаете, что результатом будет комментарий, содержащий исходный "XML" после обработки, вы смотрите на другой болезненный и сложный процесс.

Это правда, что XSLT 3.0 упрощает оба преобразования. Тем не менее, правильное решение этой проблемы лежит на авторе оригинального документа.

Содержимое комментария не считается XML- вы правы, функция набора узлов этого не делает. Вам понадобятся функции синтаксического анализа и сериализации из XSLT3, если вы действительно хотите это сделать.

Вы можете манипулировать значением комментария с помощью строковых манипуляций, возможно, здесь уже есть сотни примеров замены значения в тексте в XSL.

С вашим конкретным примером здесь вы можете просто сделать translate($xml-string,'x','y'), но я подозреваю, что ваша настоящая проблема сложнее, чем это!

Другие вопросы по тегам