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

FAQ форума XML

Оглавление

XML — общие вопросы.

Как заставить XML понимать русский язык?

  1. Настроить сервер, чтобы он выдавал в заголовках ответа правильную кодировку, например:
Content-type: text/xml; charset=windows-1251
  1. Если XML генерируется динамически, добавить аналогичный заголовок в скрипте, например:
header("Content-type: text/xml; charset=windows-1251");
  1. Указать кодировку документа, например:
<?xml version="1.0" encoding="windows-1251"?>

Программы для работы с XML

XSLT

Как скопировать с помощью XSLT весь исходный XML, кроме некоторых узлов?

Для этого используется "тождественная трансформация" (identity transformation)

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

к которой добавляется правило для узлов, которые нужно исключить:

<xsl:template match="comment()|processing-instruction()|etc" />

Почему в браузере не работают мои XSLT-шаблоны (функции в шаблонах)?

На данный момент XSLT-трансформация возможна только в Gecko-браузерах и в IE 6.0. В IE 5.0 и 5.5 также есть возможность использовать XSLT-преобразования, но нужно учитывать, что эти браузеры используют раннюю версию диалекта XSL, так называемый WD-XSL (working draft), который весьма значительно отличается от принятого позже стандарта.

При XSLT-трансформации в HTML экранируются символы в ссылках. Как отменить?

Никак. По спецификации XSLT-процессор обязан при выводе HTML экранировать символы в значениях атрибутов так, как это определено в спецификации HTML.
Спецификация XSLT

16.2 Метод вывода HTML
...
В значении атрибутов URI метод вывода html должен маскировать символы, не относящиеся к набору ASCII, используя метод, рекомендованный в главе B.2.1 Рекомендации HTML 4.0.

В том случае, если такое экранирование нежелательно, следует самостоятельно обработать соответствующие данные до (или после) трансформации.

Пространство имен по умолчанию

При создании XSLT (или при выборе узлов с помощью XPath из XML-документа) следует вводить фиктивный префикс для пространства имен по умолчанию в исходном XML-файле, иначе выражения XPath не будут работать так, как ожидается. Пример:

sample.xml:

<?xml version="1.0"?>
<root xmlns="urn:my.namespace">
    <content/>
</root>

sample.xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:my="urn:my.namespace"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  
  <xsl:template match="my:content">
     ...
  </xsl:template>
</xsl:stylesheet>

будет работать правильно, в то время как:

sample.xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns="urn:my.namespace"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="content">
    ...
  </xsl:template>
</xsl:stylesheet>

работать не будет. Объявление пространства имен по умолчанию в XSLT (xmlns="urn:my.namespace") действует только на конечные литеральные элементы в самом XSLT и никак не влияет на исходный XML-документ.

В XSLT 2.0 для решения этой проблемы есть специальный аттрибут xsl:xpath-default-namespace.

Как создавать временные деревья?

В XSLT 1.0 нет стандартных способов создания временных деревьев. Если мы напишем что-то вроде:

<xsl:variable name="nodes">
  <foo name="bar"/>
  <bar name="foo"/>
</xsl:variable>

То единственное, что мы сможем с этим сделать — скопировать в результирующий документ. Выражение XPath $nodes/foo/@name вызовет ошибку.

Подробнее см. The Extensible Stylesheet Language Transformations (XSLT) (XSLT 1.0. Проблема RTF.).

Так что, если очень надо — пользуйтесь расширениями или более поздними версиями XSLT. Если они недоступны — остается только генерить документ в несколько этапов...

Как вывести &nbsp;?

А оно действительно надо? Может быть, можно обойтись &#160;?
Нельзя? Ну, тогда — Работа с сущностями XML (&entities;)...

Как с помощью XSLT сделать...

Многие задачи подробно рассмотрены в разделе Готовые решения.

Операции с множествами -- пересечение, объединение и т.п.

По мотивам книг Майкла Кэя "XSLT. Справочник программиста" и Алексея Валикова "Технология XSLT"

TODO: Раскрыть тему 2.0 и перенести в XSLT/CookBook.

В Xpath 1.0 есть оператор объединения наборов узлов — $x|$y, но нет стандартных операторов для определения пересечения, разности множеств и т.п. В некоторых процессорах (таких как Saxon или Xalan) необходимая функциональность реализована с помощью функций расширения, однако такого же результата можно добиться средствами "чистого" XPath.
По спецификации любой набор узлов, полученный с помощью выражений XPath, не содержит дубликатов. Таким образом выражение count(.|$x) = count($x) истинно тогда и только тогда, когда текущий узел входит в набор узлов $x. Если воспользоваться этим фактом, то можно получить выражения, которые позволяют решить исходную задачу.

Объединение — $x|$y
Выражение возвращет набор узлов, состоящий из узлов $x и $y без дубликатов.

Пересечение — $x[count(.|$y) = count($y)]
Каждый узел из $x объединяется с $y и если количество узлов в новом наборе равно количеству узлов в $y, то этот узел принадлежит пересечению наборов.

Разность — $x[count(.|$y)!= count($y)]
Каждый узел из $x объединяется с $y и если количество узлов в новом наборе не равно количеству узлов в $y, то этот узел принадлежит $x, но не $y.

Симметрическая разность — $x[count(.|$y) != count($y)] | $y[count(.|$x) != count($x)]
Объединение всех узлов из наборов $x и $y, которые принадлежат либо $x, либо $y, но не обоим одновременно.

Экивалентность — count($x) = count($y) and count($x) = count($x|$y)
Два набора узлов содержат одни и те же узлы, если они имеют одно и то же количество узлов и их объединение содержит то же количество узлов.

В Xpath 2.0 для этих целей введены стандартные функции

SVG

Пример простейшего рисунка (Hello world):

hello.svg

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">   
<svg 
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="100" height="100" 
  style="stroke: black; fill: white"
 >

<defs>
  <text id="t1">Hello world!</text>    
</defs>
 
<g transform="translate(50,50)">
  <circle cx="0" cy="0" r="40"/>
  <use xlink:href="#t1" x="-32" y="0" style="stroke:blue"/>
</g>
</svg>

Как в (X)HTML включить картинку в формате SVG?

Например так:

<object type="image/svg+xml" data="hello.svg" width="100" height="100">
  <!-- SVG не поддерживаемся, грузим заменитель: -->
  <img src='hello.png' width="100" height="100" alt='Hello world!'/>
</object>

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

Powered by POEM™ Engine Copyright © 2002-2005