2016-04-27 10 views
1

私は単純で有効なDTDと、DTDに準拠していると思われる有効なXMLファイルを持っていますが、Nokogiriは多くの検証出力を生成しています。つまり、XMLファイルが検証に失敗します。Nokogiriを使用してローカルdtdファイルでxmlファイルを正しく検証するにはどうすればよいですか?

DTDファイルは以下のとおりです。

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

xmlファイルは次のとおりです。

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

私の簡単なRubyのプログラムは次のとおりです。

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) 

プログラムが検証配列の内容を出力しますこれは空ではありません。出力例:

<!DOCTYPE protocol SYSTEM "wayland.dtd"> 

としてDTDをラップ:

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

でもxmlファイルラにDOCTYPE宣言を追加した後

<!DOCTYPE protocol [ 
... 
]> 

私はまだ同じ失敗した検証を観察します出力。私は間違って何をしていますか?

+0

"[mcve]"をお読みください。コードについて質問するときは、リンク自体ではなく、質問自体に問題を複製するのに必要な最小限の情報が必要です。リンクは壊れてしまい、問題を無用にしてしまいます。 SOは単に「自分のコードで私の助けを借りてください」というサイトではなく、同じ問題を抱えている人たちを将来的に助けるための永続的な参考資料なので、将来的には単体で役立つ質問が必要です。 –

答えて

2

ParseOptionsを指定して検証を行うことができます。 doctype宣言を含むdoctypeを指定する必要があります<!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) 
関連する問題