7

REXML模块似乎支持RELAX NG 验证,但文档没有任何关于使用框架验证部分的真实信息。

您将如何使用 RELAX NG 模式验证 XML 文档?代码片段将是最有帮助的。蒂亚!

4

2 回答 2

6

好吧,我构建了一个程序,但结果并不好。

我的结论如下:

  1. rexml 松弛模式解析可能不起作用。代码说明它不完整
  2. rexml 拉解析可能有效,但很难说
  3. 以上两项均未记录在案
  4. 您应该使用真正的 XML 库,例如 libxml

这是我的测试程序:test.rb

require 'rexml/validation/relaxng.rb'
require 'rexml/parsers/pullparser.rb'

# USAGE: ruby test.rb XML-FILE
xml = ARGV[0]

# schema must be a Relax NG XML (NOT compact / .rnc)
schema = File.new( "example.rng" )
validator = REXML::Validation::RelaxNG.new( schema )

# The structure the validator made, which should be a complex structure but isn't
validator.dump

xmlfile = File.new( xml )
parser = REXML::Parsers::PullParser.new( xmlfile )
while parser.has_next?
  # Returns an PullEvent
  e = parser.pull
  # puts "Event ", e.inspect
  validator.validate(e)
end

我制作了一些玩具示例 XML 文件和 RNG 文件,然后在 OSX 10.5.x 上进行了尝试(为了使其可读,换行很长):

$ /usr/bin/ruby test.rb good.xml 
< S.1 #{doc}, :end_document(  ) >
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rexml/
  validation/validation.rb:24:in `validate': Validation error.  Expected:
  :start_element( doc ) from < S.1 #:start_element( doc ), {head}, {body},
  :end_element(  ), :end_document(  ) >  but got "doc"(  )
  (REXML::Validation::ValidationException)
        from test.rb:20

(我和 1.9 一样)

所以,几乎失败了。

(我本可以进一步优化测试程序以使用 add_listener 但这似乎不值得)

于 2009-06-01T03:43:04.553 回答
6

我在Nokogiri上取得了成功(从libxml-rubygem 切换后,因为每次使用 v1.1.3 都会出现段错误,尽管更改日志说一些 Windows 段错误问题已得到解决)。

这是我正在使用的代码:

首先,安装 Nokogiri,如果遇到问题,请查看安装教程。

gem install nokogiri

如果在 Rails 上运行,请在"Rails.root/config/enviroment.rb“”中配置 gem,例如:

config.gem 'nokogiri'

相反,只要require "nokogiri运行 Ruby。

要根据预定义的 RelaxNG 模式验证 XML 文档(我们假设文件存储在 中'public'),请使用以下代码段:

schema_path = "public/mySchema.rng"    # Or any valid path to a .RNG File
doc_path    = "public/myInstance.xml"  # Or any valid path to a .XML File

schema = Nokogiri::XML::RelaxNG(File.open(schema_path))

instance = Nokogiri::XML(File.open(doc_path))
errors = schema.validate(instance)

is_valid = errors.empty?

希望这可以帮助 !

于 2010-03-25T10:00:29.943 回答