Как мне проверить XML через RELAX NG в Ruby? - PullRequest
7 голосов
/ 27 мая 2009

Модуль REXML, похоже, поддерживает RELAX NG-валидацию , но в документах нет реальной информации об использовании валидационной части фреймворка.

Как бы вы проверили документ XML с помощью схемы RELAX NG? Фрагмент кода будет наиболее полезным. ТИА!

Ответы [ 2 ]

6 голосов
/ 25 марта 2010

У меня был успех с Nokogiri (после переключения с гема libxml-ruby, так как он каждый раз работал с segfault'ом с v1.1.3, хотя в журнале изменений сказано, что некоторые проблемы с сегфоутами Windows были решены ).

Вот код, который я использую:

Прежде всего, установите Nokogiri, взгляните на руководство по установке , если у вас есть проблемы.

gem install nokogiri

Если вы работаете на Rails, настройте гем в вашем "Rails.root/config/enviroment.rb ", например:

config.gem 'nokogiri'

И наоборот, просто require "nokogiri, если работает Ruby.

Чтобы проверить документ XML на основе предопределенной схемы RelaxNG (предположим, что файлы хранятся в '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?

Надеюсь, это поможет!

6 голосов
/ 01 июня 2009

Хорошо, я построил программу, но результаты не очень хорошие.

Мои выводы следующие:

  1. синтаксический анализ rexml relaxng, вероятно, не работает. код отмечает, что он неполный
  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, но это не показалось полезным)

...