6

I'm creating an XML document: I want to unit test at least to make sure it's well-formed. So far, I have only been able to approximate this , by using the 'hasElements' in the REXML library.

Is there a better way ? Preferably using built-in libraries (I mean libraries that ship with the standard Ruby 1.8.x distro).

require "test/unit"
require 'rexml/document'
require 'test/unit/ui/console/testrunner'

include REXML

class TestBasic < Test::Unit::TestCase

    def test_createXML
     my_xml=...create doc here...
     doc = Document.new(my_xml);
     assert(doc.has_elements?);
    end

end

Test::Unit::UI::Console::TestRunner.run(TestBasic);
Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
monojohnny
  • 5,894
  • 16
  • 59
  • 83

3 Answers3

12

You can use Nokogiri. It's not a standard Ruby library, but you can easily install it as a Gem.

begin
  bad_doc = Nokogiri::XML(badly_formed) { |config| config.options = Nokogiri::XML::ParseOptions::STRICT }
rescue Nokogiri::XML::SyntaxError => e
  puts "caught exception: #{e}"
end
# => caught exception: Premature end of data in tag root line 1
Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
  • 1
    +1 because I prefer nokogiri over libxml too. ( Uela' Simone :) ) – makevoid Jan 06 '10 at 13:02
  • Thanks - +1 - I might give this a go, but I want to avoid installing any other gems at this point ! – monojohnny Jan 06 '10 at 13:05
  • Haven't tried this yet, but it looks to be the best-fit answer here. [despite having to install another gem - but sometimes you just gotta do that!] Thanks. – monojohnny Jan 14 '10 at 15:14
3

I use LibXML to perform xml validations, here is the basic usage:

require 'libxml'

# parse DTD
dtd = LibXML::XML::Dtd.new(<<EOF)
<!ELEMENT root (item*) >
<!ELEMENT item (#PCDATA) >
EOF

# parse xml document to be validated
instance = LibXML::XML::Document.file('instance.xml')

# validate
instance.validate(dtd) # => true | false

from LibXML::DTD

And this is a link to the LibXML documentation main page.

If you don't want to use your custom validation rules you can still use a public DTD with something like:

require 'open-uri'
dtd =  LibXML::XML::Dtd.new(open("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd").read)

of course you can do much better :)

makevoid
  • 3,276
  • 2
  • 33
  • 29
  • Thanks - will check that out - I actually don't have a DTD yet - but maybe I should actually write one....I'll see if it does a simple 'well-formedness' check as well. – monojohnny Jan 06 '10 at 12:50
0

rexml - build-in library. You can use a error handler to check your xml files

require 'rexml/document'
include REXML

errormsg = ''
doc = nil
begin
  doc = Document.new(File.new(filename))
rescue
  errormsg = $!
end

puts "Fail: #{errormsg}"   if('' != errormsg)
ntfs.hard
  • 353
  • 1
  • 4
  • 16