XSL: включить некоторые символы управления ASCII, когда method="text"
У меня есть шаблон XSL, который выводит текст, а не XML. В этом тексте мне нужно включить символ ASCII 0x10 в определенной позиции.
Я понимаю, что этот символ недопустим в документе XML, но я собираюсь выводить текст, так почему мне все равно не разрешено его использовать?
Я также понимаю, что невозможно поместить этот символ буквально в шаблон, ни в CDATA
раздел ни как 
, Но почему поколение "на лету" тоже не работает? Я попытался, например, определить функцию, которая возвращает этот символ, и использовал его как <xsl:value-of select="z:get_char(16)"/>
но это также приводит к недопустимому исключению символа.
Есть ли способ?
4 ответа
Инфраструктура Microsoft .NET не поддерживает XML 1.1, это правда, но у нее есть свой собственный (не переносимый) способ использования управляющих символов в документах XML 1.0, а именно, вы можете использовать в качестве числовой ссылки на символ, если для CheckCharacters установлено значение false на ваши XmlReaderSettings/XmlWriterSettings.
Вот пример таблицы стилей и некоторый код.NET, протестированный с.NET 3.5, который не генерирует исключение недопустимого символа:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:text></xsl:text>
</xsl:template>
</xsl:stylesheet>
XmlReaderSettings xrs = new XmlReaderSettings();
xrs.CheckCharacters = false;
XslCompiledTransform proc = new XslCompiledTransform();
using (XmlReader xr = XmlReader.Create(@"sheet.xslt", xrs))
{
proc.Load(xr);
}
using (XmlReader xr = XmlReader.Create(new StringReader("<foo/>")))
{
XmlWriterSettings xws = proc.OutputSettings.Clone();
xws.CheckCharacters = false;
using (XmlWriter xw = XmlWriter.Create(@"result.txt", xws))
{
proc.Transform(xr, null, xw);
xw.Close();
}
xr.Close();
}
Поскольку XSLT-файл является XML-файлом, вы не можете включить эту символьную ссылку. Я не думаю, что вы можете сделать это в чистом решении XSLT.
Символ ASCII HEX 10/DEC 16 является управляющим символом Data Link Escape (DLE).
Спецификация XML допускает только три пробельных символа(табуляция, возврат каретки, перевод строки).
Юридическими символами являются табуляция, возврат каретки, перевод строки и юридические символы Unicode и ISO/IEC 10646.
Все остальное под 0x20 не допускается.
Диапазон символов 2 Char:: =
# x9 | #xA | #xD | [# x20- # xD7FF] | [# xE000- # xFFFD] | [# x10000- # x10FFFF] / * любой символ Unicode, за исключением суррогатных блоков, FFFE и FFFF. */
Один из вариантов - поместить значение токена-заполнителя для этого символа в ваш вывод, а затем использовать внешний процесс, чтобы найти / заменить ваш токен на символ.
Если вы можете использовать XML 1.1 (который позволяет вставлять такие символы в документ XML в качестве ссылки на символы), то должно работать следующее, по крайней мере, у меня это работает с Sun Java 6 и Saxon 9.2:
<?xml version="1.1" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<xsl:template name="main">
<xsl:text></xsl:text>
</xsl:template>
</xsl:stylesheet>
В прошлом я использовал эту технику для ввода перевода строки в текстовую область, сгенерированную XHTML. Если я не введу хотя бы один символ, текстовое поле само закроется (что приведет к проблемам браузера). Обратите внимание, что персонаж завернут в <xsl:text>
, Кроме того, оригинальный источник был в одной строке, но я отформатировал для удобства чтения.
<textarea name="qry" rows="4" cols="50" id="query">
<xsl:value-of select="$qry" /><xsl:text>
</xsl:text>
</textarea>