我尝试转换:
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::Document\ndecorators: \nnode_cache: []\nerrors:\n- !ruby/exception:Nokogiri::XML::SyntaxError\n message: |\n Start tag expected,'<' not found\n domain: 1\n code: 4\n level: 3\n file: \n line: 1\n str1: \n str2: \n str3: \n int1: 0\n column: 1\n"
任何在线XML验证器也会返回错误“Start tag expected”.我假设这是因为所有有效的XML文档都以<?xml开头,DTD文件似乎缺失了.这就是我得出的结论,即所有DTD文件都是无效的XML文件,但是,XML定义语法本身没有被定义为有效的XML确实令人感到奇怪.为什么? 我正在解析DTD文件以从XML文件中删除无效属性,知道要保留哪些属性以及要删除哪些属性,因此我需要一种方法来解析DTD文件. 最终,这只是尝试将HTML转换为ENML(Evernote标记语言)的一步.其中涉及的步骤包括:
>将HTML转换为有效的XHTML
>将主体转换为en-note元素
>根据dtd文件删除无效标签和属性
>针对dtd验证enml文件
我目前正在考虑从“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是适合这项工作的工具,但我不习惯使用它.
解决方法
However,it does feel weird to me that the xml definition Syntax itself was not defined as valid XML. I’d love to know any reasons behind this.
DTD是XML的前身SGML的延续,因此DTD不是XML文件实际上并不奇怪.在创建XML时,保留DTD及其特定语法是一个慎重的决定.
更现代的模式语言,如W3C XML Schema和RELAX NG,确实使用XML语法.
The reason I’m parsing the DTD file is that I want to remove invalid attributes from an XML file. To know which attributes to keep and which to remove,I need a way to parse the DTD file. (from question)
I am just looking for a way to parse DTD files,not just validate using them,because I want to perform custom cleanup and validation using the dtd. (from bounty text)
我真的不明白“自定义清理”是什么意思.我也没有看到尝试解析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)