2016-04-27 5 views
1

Ich habe eine einfache, gültige DTD und eine gültige XML-Datei, die der DTD zu entsprechen scheint, aber Nokogiri generiert eine Menge Validierungsausgabe, was bedeutet, dass die XML-Datei die Validierung nicht besteht.Wie validiert man eine XML-Datei mit einer lokalen dtd-Datei mit Nokogiri?

Die dtd-Datei ist:

<!ELEMENT protocol (copyright?, description?, interface+)> 
    <!ATTLIST protocol name CDATA #REQUIRED> 
<!ELEMENT copyright (#PCDATA)> 
<!ELEMENT interface (description?,(request|event|enum)+)> 
    <!ATTLIST interface name CDATA #REQUIRED> 
    <!ATTLIST interface version CDATA #REQUIRED> 
<!ELEMENT request (description?,arg*)> 
    <!ATTLIST request name CDATA #REQUIRED> 
    <!ATTLIST request type CDATA #IMPLIED> 
    <!ATTLIST request since CDATA #IMPLIED> 
<!ELEMENT event (description?,arg*)> 
    <!ATTLIST event name CDATA #REQUIRED> 
    <!ATTLIST event since CDATA #IMPLIED> 
<!ELEMENT enum (description?,entry*)> 
    <!ATTLIST enum name CDATA #REQUIRED> 
    <!ATTLIST enum since CDATA #IMPLIED> 
    <!ATTLIST enum bitfield CDATA #IMPLIED> 
<!ELEMENT entry (description?)> 
    <!ATTLIST entry name CDATA #REQUIRED> 
    <!ATTLIST entry value CDATA #REQUIRED> 
    <!ATTLIST entry summary CDATA #IMPLIED> 
    <!ATTLIST entry since CDATA #IMPLIED> 
<!ELEMENT arg (description?)> 
    <!ATTLIST arg name CDATA #REQUIRED> 
    <!ATTLIST arg type CDATA #REQUIRED> 
    <!ATTLIST arg summary CDATA #IMPLIED> 
    <!ATTLIST arg interface CDATA #IMPLIED> 
    <!ATTLIST arg allow-null CDATA #IMPLIED> 
    <!ATTLIST arg enum CDATA #IMPLIED> 
<!ELEMENT description (#PCDATA)> 
    <!ATTLIST description summary CDATA #REQUIRED> 

Die XML-Datei ist:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE protocol SYSTEM "wayland.dtd"> 
<protocol name="wayland"> 

    <copyright> 
    FOO 
    SOFTWARE. 
    </copyright> 

    <interface name="wl_display" version="1"> 
    <description summary="core global object"> 
     The core global object. This is a special singleton object. It 
     is used for internal Wayland protocol features. 
    </description> 

    <request name="sync"> 
     <description summary="asynchronous roundtrip"> 
    The sync request asks the server to emit the 'done' event 
    on the returned wl_callback object. Since requests are 
    handled in-order and events are delivered in-order, this can 
    be used as a barrier to ensure all previous requests and the 
    resulting events have been handled. 

    The object returned by this request will be destroyed by the 
    compositor after the callback is fired and as such the client must not 
    attempt to use it after that point. 

    The callback_data passed in the callback is the event serial. 
     </description> 
     <arg name="callback" type="new_id" interface="wl_callback"/> 
    </request> 
    </interface> 

</protocol> 

Mein einfaches Ruby-Programm ist:

require 'nokogiri' 

DTD_PATH = "wayland.dtd" 
XML_PATH = "wayland.xml" 

dtd_doc = Nokogiri::XML::Document.parse(open(DTD_PATH)) 
dtd = Nokogiri::XML::DTD.new('protocol', dtd_doc) 
doc = Nokogiri::XML(open(XML_PATH)) 
puts dtd.validate(doc) 

Das Programm druckt den Inhalt des Validierungs Array , die nicht leer ist. Beispielausgabe:

No declaration for attribute name of element request 
No declaration for element description 
No declaration for attribute summary of element description 

Auch nach dem Hinzufügen einer DOCTYPE Erklärung zum XML-Datei a la:

<!DOCTYPE protocol SYSTEM "wayland.dtd"> 

Und das Einwickeln der DTD mit:

<!DOCTYPE protocol [ 
... 
]> 

beobachte ich immer noch die gleichen Fehler bei der Überprüfung Ausgabe. Was mache ich falsch?

+0

Bitte lesen Sie "[mcve]". Wenn wir nach Code fragen, benötigen wir die minimalen Informationen, die notwendig sind, um das Problem in der Frage selbst zu kopieren, NICHT in Links. Links verrotten dann und brechen die Frage unbrauchbar. SO ist nicht nur eine "Hilf mir mit meinem Code" -Seite, es ist eine dauerhafte Referenz, um anderen in der Zukunft mit dem gleichen Problem zu helfen, daher die Notwendigkeit von Fragen, die eigenständig und in der Zukunft nützlich sind. –

Antwort

2

Sie können die Validierung durchführen, indem Sie ParseOptions angeben. Sie müssen den Doctype mit Doctype-Deklaration angeben <!DOCTYPE protocol SYSTEM "wayland.dtd">

require 'nokogiri' 

DTD_PATH = "wayland.dtd" 
XML_PATH = "wayland.xml" 

xml = File.read(XML_PATH) 
options = Nokogiri::XML::ParseOptions::DTDVALID 
doc = Nokogiri::XML::Document.parse(xml, nil, nil, options) 
puts doc.external_subset.validate(doc)