Обработка XML-файла с общедоступным типом документа - PullRequest
2 голосов
/ 10 мая 2010

Я пытаюсь обработать файл SVG с помощью XSLT. У меня такое поведение, которого я не понимаю, это связано с объявлением типа документа.

Вот два теста, которые я сделал. Первый дает мне ожидаемый результат, а второй дает мне результат, который я не понимаю. (проверено с саксоном и ксаланом).

Таблица стилей, использованная для двух тестов:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="text" encoding="UTF-8"/>

    <xsl:template match="text()" >
    </xsl:template>

    <xsl:template match="/">
        <xsl:text>/</xsl:text>
        <xsl:apply-templates />
    </xsl:template>


    <xsl:template match="svg">
        <xsl:text>svg</xsl:text>
        <xsl:apply-templates />
    </xsl:template>
</xsl:stylesheet>

Испытание № 1

исходный файл:

<?xml version="1.0"?>
<svg width="768" height="430">

</svg>

результат:

/svg

Испытание № 2

исходный файл:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN"
"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">
<svg width="768" height="430">

</svg>

результат:

/

Почему объявление doctype изменяет поведение обработки?

1 Ответ

1 голос
/ 10 мая 2010

Элементы SVG находятся в пространстве имен SVG .

DTD определяет это, поэтому:

<xsl:template match="svg"> 

соответствует элементу с именем svg, но без пространства имен.Все элементы в документе XML находятся в пространстве имен SVG, и этот шаблон не соответствует ни одному узлу.

Это объясняет вывод.

Решение : заменить шаблонсовпадение svg с тем, которое соответствует svg в пространстве имен SVG, как в следующем преобразовании:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:s="http://www.w3.org/2000/svg"
 >
    <xsl:output method="text" encoding="UTF-8"/>

    <xsl:template match="text()" >
    </xsl:template>

    <xsl:template match="/">
        <xsl:text>/</xsl:text>
        <xsl:apply-templates  />
    </xsl:template>


    <xsl:template match="s:svg">
        <xsl:text >svg</xsl:text>
        <xsl:apply-templates  />
    </xsl:template>
</xsl:stylesheet>

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

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN"
"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">
<svg width="768" height="430" >

</svg>

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

/svg

Обновление :

Несколько человек спрашивали меня "Как DTDможет установить пространство имен (по умолчанию)? "

Вот ответ: XML и DTD с ним были сделаны Рекомендацией W3C до того, как пространства имен сделали это.В XML до пространства имен объявление пространства имен является просто атрибутом.

DTD могут указывать «атрибуты по умолчанию» - атрибуты, которые могут быть пропущены из экземпляра, но будут автоматически добавлены с помощьюзначение по умолчанию.

Таким образом, один из способов определения пространства имен по умолчанию в DTD - это определение атрибута по умолчанию xmlns для верхнего элемента документа.

...