如何在 Ruby 中解析 DTD 文件



我试图将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::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 验证器也会返回错误"预期的开始标记"。我认为这是因为所有有效的XML文档都以<?xml开头,DTD文件似乎丢失了。这就是我得出所有 DTD 文件都是无效 XML 文件的结论,但是,XML 定义语法本身没有定义为有效的 XML 确实感觉很奇怪。为什么?

我正在解析 DTD 文件以从 XML 文件中删除无效属性,以了解要保留哪些属性以及要删除哪些属性,因此我需要一种方法来解析 DTD 文件。

最终,这只是尝试将HTML转换为ENML(Evernote Markup Language(的一个步骤。其中涉及的步骤包括:

  • 将 HTML 转换为有效的 XHTML
  • 将正文转换为注释元素
  • 根据 dtd 文件删除无效的标记和属性
  • 根据 dtd 验证 enml 文件

我目前正在考虑从"了解 Evernote 标记语言"中复制不允许的属性和标签,并使用它来验证我的 XHTML,但我更喜欢使用 DTD 作为我的源代码。

Nokogiri DTD 类是一个 Node 类,用于保存内联 DTD 节点并对其进行验证。就我而言,我有一个使用 SYSTEM 属性指定的外部 DTD 文件,Nokogiri 似乎不支持该文件。即使它确实有效,我得到的只是验证。

我确实使用以下方法进行了验证以正常工作:

#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是适合这项工作的工具,但我不够习惯使用它。

但是,我确实觉得 xml 定义语法本身没有定义为有效的 XML。我很想知道这背后的任何原因。

DTD

是XML的前身SGML的延续,所以DTD不是XML文件实际上并不奇怪。保留 DTD 及其特定语法是创建 XML 时经过深思熟虑的决定。

更现代的模式语言,如W3C XML Schema和RELAX NG,确实使用XML语法。

<小时 />

我解析 DTD 文件的原因是我想从 XML 文件中删除无效属性。要知道要保留哪些属性以及要删除哪些属性,我需要一种方法来解析 DTD 文件。(来自问题(

我只是在寻找一种解析 DTD 文件的方法,而不仅仅是使用它们进行验证,因为我想使用 dtd 执行自定义清理和验证。

我真的不明白你所说的"自定义清理"是什么意思。我也看不出首先尝试解析 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, nil, options)
puts doc.external_subset.validate(doc) 

如果此代码没有输出,则 XML 文档对 DTD 有效。

相关内容

  • 没有找到相关文章

最新更新