Xpoint
   [напомнить пароль]

Работа с сущностями XML (&entities;)

Оглавление

Проблема.

Требуется ввести именованную сущность (например —  ).

  • В исходном документе
  • В преобразовании
  • В результирующем документе

Стандартное решение

В исходном документе и преобразовании

Задача решается указанием в документе соответствующего DTD:

<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE xsl:stylesheet[
  <!ENTITY nbsp "&#160;">
]>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 >
 <!-- Теперь здесь можно использовать &nbsp; -->

И то же самое в исходном xml.

Чтобы не прописывать всякий раз все используемые в html entity можно вставить в DTD ссылку на их определение:

<!ENTITY % HTMLlat1 PUBLIC
  "-//W3C//ENTITIES Latin 1 for XHTML//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
%HTMLlat1;

<!ENTITY % HTMLspecial PUBLIC
  "-//W3C//ENTITIES Special for XHTML//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
%HTMLspecial;

<!ENTITY % HTMLsymbol PUBLIC
  "-//W3C//ENTITIES Symbols for XHTML//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
%HTMLsymbol;

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

В результирующем документе

Хорошего решения в рамках XSLT 1.0 и 1.1 не существует.

Остается писать

<xsl:text disable-output-escaping = 'yes'>&amp;nbsp;</xsl:text>

и надеяться, что получится именно то, что надо.

Вообще, если возникла потребность в такого рода ухищрениях, следует очень хорошо подумать, насколько это нужно. Действительно, какая разница, что окажется в браузере пользователя — &nbsp; или &#160;? Для него это одно и то же...

Карты символов XSLT 2.0

В XSLT 2.0 для решения этой задачи введен специальный элемент xsl:character-map. Рассмотрим простейший пример его использования:

<xsl:stylesheet version="2.0"
  exclude-result-prefixes="xsl"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 >

<xsl:output method='xhtml' indent='yes' use-character-maps="latin1"/>

<xsl:character-map name="latin1">
  <xsl:output-character character="&#160;" string="&amp;nbsp;" />
  <!-- ... -->
</xsl:character-map>
 
<xsl:template match='/'>
 <html>
  <body>
   <p>No&#160;break&#160;space</p>
  </body>
 </html>
</xsl:template>
               
</xsl:stylesheet>

На любом входном документе это преобразование выдаст:

<html xmlns="http://www.w3.org/1999/xhtml">
   <body>
      <p>No&nbsp;break&nbsp;space</p>
   </body>
</html>

Заметим, что сам процессор ничего не знает про сущность &nbsp; — мы указали ему, что в выходном документе нужно менять символ неразрывного пробела на вышеозначенную последовательность символов, и только.

Использование карт симоволов, разумеется, не ограничивается только сущностями. С их помощью можно заменить любой символ на что угодно. И, таким образом, получить на выходе документ, не являющийся валидным XML — например, скрипт на ASP...

За подробностями отсылаю читателей к разделу «Character Maps» спецификации.

Powered by POEM™ Engine Copyright © 2002-2005