Преобразовать атрибут в закомментированный 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')
, но я подозреваю, что ваша настоящая проблема сложнее, чем это!