Не конвертировать> в> в XSLT - PullRequest
7 голосов
/ 22 ноября 2010

У меня есть XML, который выглядит как

<?xml version="1.0"?>
<root>
    <![CDATA[
    > foo 
    ]]>
</root>

(обратите внимание на знак> "> foo") и таблицу стилей XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
    <foo><xsl:value-of select='.'/></foo>
</xsl:template>
</xsl:stylesheet>

Когда я бегу xsltproc stylesheet.xsl data.xml, я получаю

<?xml version="1.0"?>
<foo>

    &gt; foo

</foo>

но я хочу получить вывод

<?xml version="1.0"?>
<foo>

    > foo

</foo>

т.е. оставьте «>» как есть, вместо того, чтобы преобразовывать его в сущность. Как мне это сделать?

Ответы [ 3 ]

8 голосов
/ 22 ноября 2010

@ Одед, @ хачик,

Попробуйте проверить его желаемый результат на правильность формирования .Это действительно правильно оформленный XML.(«Действительный» здесь даже не вопрос, так как здесь нет схемы.)

Распространенным заблуждением является то, что «>» недопустимо в правильно сформированном XML.В большинстве случаев «<» недопустимо, но «>» допустимо везде, за одним редким исключением. соответствующий параграф спецификации:

Символ амперсанда (&) и левая угловая скобка (<) НЕ ДОЛЖНЫ появляться в их буквальной форме, за исключением случаев, когда они используются в качестве разделителей разметки.или внутри комментария, инструкции по обработке или раздела CDATA.Если они нужны где-то еще, они ДОЛЖНЫ быть экранированы с использованием либо числовых ссылок на символы, либо строк «&» и «<» соответственно.Правая угловая скобка <strong>(>) может быть представлена ​​с использованием строки ">", и ДОЛЖНА, для совместимости, экранироваться с использованием либо ">", либо ссылки на символ , когда она появляется в строке "]]> "по содержанию, , когда эта строка не отмечает конец раздела CDATA.

В XSLT 2.0« правильный »способ сделать то, что вы хотите, - это использовать <xsl:character-map>.С XSLT 1.0, я думаю, что единственный способ принудительно использовать «>» в ​​выходных данных - это использовать disable-output-escaping , как и предложил @khachik.Однако обратите внимание, что процессоры XSLT не обязаны соблюдать DOE или карты символов , а некоторые не могут (например, если они находятся в конвейере и не подключены к сериализации).Но вы, вероятно, уже знаете, можете ли вы это сделать, а если нет, вам нужно будет решить проблемы с сериализацией в конце конвейера.

Однако, стоит спросить, почему вы хотите, чтобы ">" сериализовалось как ">"?Как видно из спецификации,> - это вполне приемлемый способ выразить точно такую ​​же информацию, что касается XML.Ни один нижестоящий пользователь XML не должен знать разницу или заботу.Хотите ли вы его по эстетическим соображениям?

Обновление: ОП хочет, чтобы, поскольку вывод должен быть не только правильно сформированным XML, он также должен быть правильно сформированным Literate Haskell.

4 голосов
/ 22 ноября 2010

Добавление к очень хорошему объяснению @ LarsH :

Если ваш XSLT-процессор позволяет DOE , тогда вы можете использовать :

  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/root">
        <foo><xsl:value-of select='.' disable-output-escaping="yes"/></foo>
    </xsl:template>
  </xsl:stylesheet>

и когда это преобразование применяется к предоставленному документу XML :

<?xml version="1.0"?>
<root>
    <![CDATA[
    > foo
    ]]>
</root>

желаемый результат получается :

<foo>
    > foo
    </foo>
1 голос
/ 22 ноября 2010

<xsl:value-of select='.' disable-output-escaping="yes"/> но это не будет правильно сформированный XML.

Обновление С > это будет хорошо сформировано. (С < не будет.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...