2009-04-06 13 views
3

Ich bin für meine benutzerdefinierte XML-Datei eine separate .dtd Datei als Doctype verwenden:Mit einem Doctype mit XML

names.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> 

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 "é"> 

Beim Versuch, auf names.xml zuzugreifen, erhalte ich jedoch die folgende Fehlermeldung:

XML Parsing Error: undefined entity Location: http://localhost/.../names.xml Line Number 5, Column 18:

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

Nur zur Klarstellung names.xml und names.dtd sind im selben Verzeichnis und http://localhost/.../names.dtd entweder nicht funktioniert.

Dies scheint zu funktionieren, wenn Sie die <!ENTITY innerhalb einer <!DOCTYPE in names.xml jedoch setzen. Kann jemand dazu beraten?

Antwort

2

Wenn Sie das Dokument in Firefox öffnen, um herauszufinden, ob Sie die TTD korrekt haben, tun Sie dies nicht. Firefox übergibt die XML- und DTD-Dateien nicht über einen geeigneten XML-Parser. Öffnen Sie Ihr XML-Dokument im IE, wodurch Ihr Dokument durch den MSXML-Parser geleitet wird.

Wenn Sie das XML-Dokument im IE öffnen, wird ein Fehler bezüglich Ihrer DTD mit ungültigen Zeichen ausgelöst. Sie müssen den Zeichencode für das eacute und nicht das Zeichen selbst verwenden. Hier ist der Code, den ich an der Arbeit ...

<?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> 

und

<!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;"> 
+0

Sie können das Zeichen 'é' direkt im externen DTD-Betreff verwenden, wenn es OK codiert ist. Standardmäßig sollte es in UTF-8 sein; Sie können dies ändern, indem Sie eine "Textdeklaration" am oberen Rand der .dtd mit einer anderen "Codierung" einfügen. (Eine Textdeklaration entspricht im Wesentlichen der -Deklaration.) – bobince

+0

Übrigens ist es für einen XML-Parser legal, externe Referenzen wie die externe DTD-Teilmenge nicht einzubeziehen, und es ist gut, dass Browser es auf Webseiten nicht zulassen da es Cross-Site-Scripting ermöglichen könnte. Was bei nicht deklarierten Entitätsreferenzen in diesem Fall passiert, ist implementierungsdefiniert. – bobince

+0

Korrektur: Firefox verwendet einen korrekten XML-Parser, aber der Entity Resolver (die Sache, die System-IDs in Byte-Streams auflöst) wurde gehackt, um externe DTDs in Streams nullter Länge aufzulösen. – hsivonen

2

Firefox does not load external DTDs (noch Safari; es looks like keine Browser tun). Ihre DTD & XML funktionieren in xmllint, wenn ich sagen, dass es externe DTDs zu laden:

$ 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> 

bearbeiten: Wie hsivonen in den Kommentaren weist darauf hin, DTDs mit externen Einrichtungen zu lösen, ist ein bad idea. Sie sollten im Allgemeinen keine DOCTYPEs oder DTDs im Internet verwenden. Wenn Sie ein Dokument validieren möchten, sollten Sie ein separates Schema verwenden (RELAX NG wird für diesen Zweck empfohlen) und keine eingebettete DTD im Dokument selbst.

+0

Es ist eine sehr schlechte Idee wäre für den Browser-DTDs zu laden: http://hsivonen.iki.fi/no- dtd/ – hsivonen

+0

Ja, du hast Recht. Ich habe mich gefragt, ob einige von ihnen sogar lokale DTDs geladen haben. Gute Referenz, warum DTDs eine schlechte Idee sind. –

+0

@hsivonen Meine Antwort wurde aktualisiert, um Informationen darüber zu enthalten, warum DTDs eine schlechte Idee sind; Danke für den guten Artikel dazu. –