【发布时间】:2014-07-12 16:31:13
【问题描述】:
我试图将 DTD 文件转换为 YAML 文件,并尝试在 libXML 和 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::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 验证器也会返回错误“预期开始标记”。我认为这是因为所有有效的 XML 文档都以 <?xml 开头,而似乎缺少这些 DTD 文件。这就是让我得出所有 DTD 文件都是无效 XML 文件的结论的原因,然而,XML 定义语法本身没有被定义为有效 XML 确实让人感到奇怪。为什么?
我正在解析 DTD 文件以从 XML 文件中删除无效属性,以了解要保留哪些属性以及要删除哪些属性,因此我需要一种方法来解析 DTD 文件。
最终,这只是尝试将 HTML 转换为 ENML(Evernote 标记语言)的一个步骤。其中涉及的步骤包括:
- 将 HTML 转换为有效的 XHTML
- 将正文转换为注释元素
- 根据 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,但要使用它,我需要一个标签列表->属性(每个标签都可以使用哪些属性)。我没有在清理结束时进行多次验证文档,而是循环遍历每个 XML 标记并清理它们。但要知道 如何 清理它们,我需要知道有效架构中支持哪些标签和元素。因此,我需要解析 DTD 文件。
据我了解,XLST 是适合这项工作的工具,但我觉得使用它不够舒适。
【问题讨论】:
-
你能分享一下你对 libxml 和 nokogiri 的尝试吗?例如,您是否使用过 Nokogiri::XML::DTD (nokogiri.org/Nokogiri/XML/DTD.html) 或使用 REXML 的 DTD 解析器 (rubydoc.info/stdlib/rexml/REXML/DTD/Parser)
-
您的输入 XML 文件开始时格式不正确?我对你到底在做什么有点模糊;听起来你正在做转换,它不需要首先匹配 DTD——使用 XSLT 或更合理的等效项并过滤掉你不想要的/添加你所做的等等。
-
我只是想将 DTD 文件转换为 ruby 哈希。你会怎么做呢? (我会同时研究 XSLT)
-
我添加了更多关于我正在尝试做的事情的详细信息。
-
“执行自定义清理”是什么意思?为什么仅仅根据 DTD 验证 XML 文件还不够?
标签: ruby xml nokogiri dtd evernote