Символы ISO-8859-1 рассматриваются как UTF-8 в атрибутах XSLT - PullRequest
3 голосов
/ 22 января 2012

Символ ¬ (0xAC в ISO-8859-1) работает для обычного текста, если я гарантирую, что ISO-8859-1 всегда используется в качестве кодировки повсюду.Однако при использовании его в атрибутах он экранируется до: %C2%AC.Я понимаю, что для URL-адресов его необходимо экранировать, но не для того, чтобы экранировать его так же, как для UTF-8, а не просто %AC, как я ожидал бы для ISO-8859-1.

Поскольку экранирование находится в выходном html-файле, единственный вывод заключается в том, что причиной является процессор xslt.

Пример:

, который для меня создает:

Вывод был сгенерирован с использованием xsltproc, скомпилировано с libxml 20707, libxslt 10126 и libexslt 815. Это было на #!Linux (amd64).Я также пытался: xmlstarlet tr (также использует libxml), xalan и Google Chrome (добавив <?xml-stylesheet ... >, см. input_ss.xml тег) с тем же результатом.

Opera вообще не избегает этого, и позволяет буквально использовать ¬ в URL и атрибуте.

Это стандартное поведение для xslt или это ошибка в способе экранирования атрибутов?И в любом случае, есть ли решение, отличное от замены %C2%AC на %AC, учитывая, что это почти наверняка то же самое для других символов, которые соответствуют ISO-8859-1 и недопустимы в UTF-8.

Ответы [ 2 ]

3 голосов
/ 23 января 2012

Здесь используются три разные текстовые технологии: XML, HTML и URI.

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

Знак без знака ¬ (U + 00AC) в первых двух может быть экранирован как &#xAC;или &#172; возможно, с некоторыми ведущими нулями, как в XML, так и в HTML (&not; также будет работать в HTML).Этот escape будет использоваться независимо от того, в какой кодировке находится XML или HTML, потому что он относится к символу ¬, а не к его набору октетов в данной кодировке символов - в действительности, мы обычно используем его только в случае, когдав используемой кодировке такого набора октетов не было.

В этом случае это не нужно, поскольку выходные данные находятся в кодировке символов, в которой нет необходимости экранировать их, и поэтому в источникевы можете видеть The ¬ character без экранирования.

Этот HTML-код включает в себя текст URI.Кодировка HTML не имеет к этому никакого отношения, потому что кодировка - это то, как мы получаем текст HTML с одной машины на другую, но когда HTML-код анализируется для чтения этого URI, мы переходим к этой точке и имеем делос некоторым текстом на уровне текста - то есть у него больше нет кодировки.

Теперь у URI есть свои собственные механизмы выхода.Это необходимо использовать в случае ¬, так как это недопустимый символ в URI (в отличие от IRI).К сожалению, в отличие от экранирования в XML и HTML, эти экранирования основаны на октетах в заданной кодировке, а не на кодовой точке самого символа.

Теперь легко увидеть это как ошибку, но URI былиуказано в 1994 году и формализованная работа восходит к 1989/1990 году, в то время как Unicode 1.0 был выпущен в 1991 году и не имел революционных 2.0 до 1996 года, поэтому задним числом имеет значительно больше преимуществ, чем изобретатели URI.(У HTML была та же проблема много лет назад, но формат ее кодировок значительно облегчил ее решение без многих проблем обратной совместимости).

Итак, какую кодировку мы должны использовать для этих октетов?Оригинальные спецификации оставили это неопределенным, но на самом деле единственный возможный выбор - UTF-8.Это единственная кодировка, которая дает этим выходам, обычно используемым для символов, специально предназначенных для URI, их выходы в диапазоне 0x20 - 0x7F, и в то же время покрывающим все UCS.

Также нет способа указать, что другой выбор может быть более подходящим.Помните, мы работаем на уровне текста, поэтому использование ISO-8859-1 совершенно не имеет значения.Даже если мы отслеживали кодировку при разборе HTML, URI будет использоваться таким образом, который не имеет ничего общего с документом, поэтому мы по-прежнему не можем его использовать.В общем, если нам нужно использовать кодирование на основе октетов, и мы должны сохранять символы в диапазоне ASCII, совпадающие с октетами, которые они имели бы в ASCII, единственно возможная основа для кодирования - это UTF-8.

По этой причине экранирование в любом URI для ¬ всегда должно быть %C2%AC.

Могут быть некоторые устаревшие системы, которые ожидают, что URI будут использовать другие кодировки,но решение состоит в том, чтобы исправить бит, который сломан, а не бит, который работает, поэтому, если что-то ожидает, что ¬ будет %AC, то поймайте его близко к этому, преобразовав %C2%AC близко к его использованию (и если он выводит %AC, то, конечно, вам нужно исправить его на %C2%AC, прежде чем он попадет во внешний мир).

2 голосов
/ 23 января 2012

В спецификации XSLT говорится, что при сериализации атрибутов, имеющих значение URI, все символы, не входящие в ASCII, экранируются с использованием% HH-экранирования октетов UTF-8, которые представляют символ. Хотя% HH-экранирование других кодировок использовалось в прошлом, сегодня оно больше не используется. Это совершенно не зависит от кодировки самого документа.

...