Использование типа документа с XML

Я использую отдельный файл .dtd в качестве типа документа для своего пользовательского файла xml:

имена.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE name SYSTEM "names.dtd">
<names>
    <name>
        <text>Pep&eacute;</text>
        <creator>&lost;</creator>
        <history>&lost;</history>
    </name>
    <name>
        <text>Charles</text>
        <creator>James</creator>
        <history>&lost;</history>
    </name>
</names>

имена.dtd

<!ELEMENT name (text, creator+, history)>
<!ELEMENT text (#PCDATA)>
<!ELEMENT creator (#PCDATA)>
<!ELEMENT history (#PCDATA)>

<!-- Placeholder/unknown history or creator name -->
<!ENTITY lost "Lost in the depths of time.">
<!ENTITY eacute "é">

Однако при попытке доступа к named.xml я получаю следующую ошибку:

Ошибка синтаксического анализа XML: неопределенный объект Местоположение: http://localhost/.../names.xml Строка номер 5, столбец 18:

<text>Pep&eacute;</text>
---------^

Просто для пояснения, что имена.xml и name.dtd находятся в одном каталоге и используют http://localhost/.../names.dtd тоже не работает.

Однако это работает, если поместить <!ENTITY внутри <!DOCTYPE в names.xml. Кто-нибудь может посоветовать по этому поводу?


person Ross    schedule 06.04.2009    source источник


Ответы (2)


Если вы открываете документ в Firefox, чтобы попытаться выяснить, правильно ли вы указали dtd, не делайте этого. Firefox не пропускает xml и dtd через правильный синтаксический анализатор xml. Откройте свой XML-документ в IE, что приведет к тому, что ваш документ будет передан через синтаксический анализатор MSXML.

При открытии XML-документа в IE выдается ошибка о том, что ваш DTD использует недопустимые символы. Вам нужно использовать код символа для eacute, а не сам символ. Вот код, который я получил для работы...

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE NAME SYSTEM "names.dtd">
<names>
    <name>
        <text>Pep&eacute;</text>
        <creator>&lost;</creator>
        <history>&lost;</history>
    </name>
    <name>
        <text>Charles</text>
        <creator>James</creator>
        <history>&lost;</history>
   </name>
</names>

и

<!ELEMENT name (text, creator+, history)>
<!ELEMENT text (#PCDATA)>
<!ELEMENT creator (#PCDATA)>
<!ELEMENT history (#PCDATA)>

<!ENTITY lost "Lost in the depths of time.">
<!ENTITY eacute "&#233;">
person Justin Niessner    schedule 06.04.2009
comment
Вы можете использовать символ «é» непосредственно во внешней теме DTD, если он закодирован правильно. По умолчанию он должен быть в UTF-8; вы можете изменить это, включив «текстовое объявление» в верхней части .dtd с другой «кодировкой». (Текстовое объявление в основном совпадает с объявлением ‹?xml?›.) - person bobince; 06.04.2009
comment
Между прочим, синтаксический анализатор XML может не включать внешние ссылки, такие как внешнее подмножество DTD, и хорошо, что браузеры не разрешают это на веб-страницах, поскольку это может позволить межсайтовый скриптинг. То, что происходит с необъявленными ссылками на объекты в этом случае, определяется реализацией. - person bobince; 06.04.2009
comment
Исправление: Firefox использует правильный синтаксический анализатор XML, но преобразователь сущностей (вещь, которая разрешает системные идентификаторы в потоки байтов) был взломан для преобразования внешних DTD в потоки нулевой длины. - person hsivonen; 07.04.2009

Firefox не загружает внешние DTD (как и Safari; он похоже, что браузеры этого не делают). Ваши DTD и XML отлично работают в xmllint, если я скажу загрузить внешние DTD:

$ xmllint --loaddtd names.xml 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE names SYSTEM "names.dtd">
<names>
    <name>
        <text>Pep&eacute;</text>
        <creator>&lost;</creator>
        <history>&lost;</history>
    </name>
    <name>
        <text>Charles</text>
        <creator>James</creator>
        <history>&lost;</history>
    </name>
</names>

изменить: как отмечает в комментариях Хсивонен, использование DTD для разрешения внешних сущностей является плохая идея. Как правило, вы не должны использовать DOCTYPE или DTD в Интернете. Если вы хотите проверить документ, вам следует использовать отдельную схему (для этой цели рекомендуется RELAX NG), и не DTD, встроенный в сам документ.

person Brian Campbell    schedule 06.04.2009