如何在Ruby中解析DTD文件
我试图将DTD文件转换为YAML文件,我尝试在lib
XML和Nokogiri中加载它,但似乎DTD文件不是有效的XML文件.只要我可以解析DTD文件,我就可以使用任何第三方gem.
我尝试转换: wget "http://xml.evernote.com/pub/enml2.dtd" irb require 'nokogiri' xml = Nokogiri::XML::Document.parse('enml2.dtd') xml.to_yaml => "--- !ruby/object:Nokogiri::XML::Documentndecorators: nnode_cache: []nerrors:n- !ruby/exception:Nokogiri::XML::SyntaxErrorn message: |n Start tag expected,'<' not foundn domain: 1n code: 4n level: 3n file: n line: 1n str1: n str2: n str3: n int1: 0n column: 1n" 任何在线XML验证器也会返回错误“Start tag expected”.我假设这是因为所有有效的XML文档都以<?xml开头,DTD文件似乎缺失了.这就是我得出的结论,即所有DTD文件都是无效的XML文件,但是,XML定义语法本身没有被定义为有效的XML确实令人感到奇怪.为什么? 我正在解析DTD文件以从XML文件中删除无效属性,知道要保留哪些属性以及要删除哪些属性,因此我需要一种方法来解析DTD文件. 最终,这只是尝试将HTML转换为ENML(Evernote标记语言)的一步.其中涉及的步骤包括: 我目前正在考虑从“Understanding the Evernote Markup Language”复制不允许的属性和标签,并使用它来验证我的XHTML,但我更喜欢使用DTD作为我的来源. Nokogiri DTD类是一个Node类,用于保存内联DTD节点并对其进行验证.在我的情况下,我有一个使用SYSTEM属性指定的外部DTD文件,即Nokogiri does not seem to support.即使它确实有效,我所得到的只是验证. 我确实使用以下方法进行验证: #dtd = XML::Dtd.new File.read Rails.root.join('lib','assets','enml2.dtd') #enml_document = XML::Document.string enml #ret = enml_document.validate dtd 我没有尝试过REXML.我会给你一个回报并报告. 我正在尝试将HTML文档转换为使用给定DTD验证的XML文档. ENML架构中不允许使用大多数HTML元素和属性,因此我必须将其删除或删除它们.我还需要知道哪些属性是允许的,哪些不是,这样我就可以正确地解析XML并删除/清理有问题的元素和属性. 为了清理目的,我使用Loofah,但要使用它,我需要一个tag->属性列表(每个标签都有这些属性).我没有进行多次验证文档,而是在清理结束时进行验证,而只是循环遍历每个XML标记并清理它们.但是要知道如何清理它们,我需要知道有效模式中支持哪些标记和元素.因此,我需要解析DTD文件. 根据我的理解,XLST是适合这项工作的工具,但我不习惯使用它. 解决方法
DTD是XML的前身SGML的延续,因此DTD不是XML文件实际上并不奇怪.在创建XML时,保留DTD及其特定语法是一个慎重的决定. 更现代的模式语言,如W3C XML Schema和RELAX NG,确实使用XML语法.
我真的不明白“自定义清理”是什么意思.我也没有看到尝试解析DTD的重点. 为了确定XML文件中的任何元素或属性是否无效(如果它们违反了关联DTD中的规则),您需要使用验证XML解析器来解析XML文件.然后解析器会告诉您是否有任何需要修复的错误. Nokogiri基于libxml2,它提供了一个验证解析器.它支持使用<!DOCTYPE foo SYSTEM“bar.dtd”>指定的外部DTD.语法(如何使这项工作显示在您引用的问题的注释中:https://github.com/sparklemotion/nokogiri/issues/440#issuecomment-3031164). 以下是验证的完成方式: require 'nokogiri' xml = File.read("yourfile.xml") options = Nokogiri::XML::ParSEOptions::DTDLOAD # Needed for the external DTD to be loaded doc = Nokogiri::XML::Document.parse(xml,nil,options) puts doc.external_subset.validate(doc) 如果此代码没有输出,则XML文档对DTD有效. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |