Libxml 0.3.8 - How to validate document with schema?

Hello all (Ross),

I'm trying to get libxml to validate an XML::Document using #validate with
an XML::Schema.

Can one of you describe to me what is wrong ?

I have this, with the examples pasted at the end of this post. This is from
the W3Schools example at :
http://www.w3schools.com/schema/schema_example.asp

$ irb
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'xml/libxml'
=> true
irb(main):003:0> xml = XML::Document.new('shiporder.xml')
=> <?xml version="shiporder.xml"?>

irb(main):004:0> sch = XML::Schema.from_string(File.open('shiporder.xsd
').read)
=> #<XML::Schema:0x365c54>
irb(main):005:0> xml.validate sch
error -- found validity error: no root element
=> false
irb(main):006:0>

============ shiporder.xml ===============
<?xml version="1.0" encoding="ISO-8859-1"?>

<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
  <name>Ola Nordmann</name>
  <address>Langgt 23</address>
  <city>4000 Stavanger</city>
  <country>Norway</country>
</shipto>
<item>
  <title>Empire Burlesque</title>
  <note>Special Edition</note>
  <quantity>1</quantity>
  <price>10.90</price>
</item>
<item>
  <title>Hide your heart</title>
  <quantity>1</quantity>
  <price>9.90</price>
</item>
</shiporder>
============ shiporder.xml ===============

============ shiporder.xsd ===============
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:simpleType name="stringtype">
<xs:restriction base="xs:string"/>
</xs:simpleType>

<xs:simpleType name="inttype">
<xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>

<xs:simpleType name="dectype">
<xs:restriction base="xs:decimal"/>
</xs:simpleType>

<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
  <xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>

<xs:complexType name="shiptotype">
<xs:sequence>
  <xs:element name="name" type="stringtype"/>
  <xs:element name="address" type="stringtype"/>
  <xs:element name="city" type="stringtype"/>
  <xs:element name="country" type="stringtype"/>
</xs:sequence>
</xs:complexType>

<xs:complexType name="itemtype">
<xs:sequence>
  <xs:element name="title" type="stringtype"/>
  <xs:element name="note" type="stringtype" minOccurs="0"/>
  <xs:element name="quantity" type="inttype"/>
  <xs:element name="price" type="dectype"/>
</xs:sequence>
</xs:complexType>

<xs:complexType name="shipordertype">
<xs:sequence>
  <xs:element name="orderperson" type="stringtype"/>
  <xs:element name="shipto" type="shiptotype"/>
  <xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
</xs:sequence>
<xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>

<xs:element name="shiporder" type="shipordertype"/>

</xs:schema>
============ shiporder.xsd ===============

···

--
------------------------------
Apple MacBook. Black. It's the new White!
------------------------------
Peter Fitzgibbons

Hi,

Hello all (Ross),

I'm trying to get libxml to validate an XML::Document using #validate with
an XML::Schema.

Can one of you describe to me what is wrong ?

irb(main):003:0> xml = XML::Document.new('shiporder.xml')
=> <?xml version="shiporder.xml"?>

Problem here - The argument to XML::Document.new is interpreted as the
XML version to use, rather than as a file to read (notice the XML
version is your filename). Try this instead:

xml = XML::Document.file('shiporder.xml')
# => <?xml version="1.0" encoding="ISO-8859-1"?>
# <shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot;
orderid="889923"
# xsi:noNamespaceSchemaLocation="shiporder.xsd">
# < ... snipped ... >
# </shiporder>

irb(main):004:0> sch = XML::Schema.from_string(File.open('shiporder.xsd
').read)

(side note, I'd just use File.read('shiporder.xsd') here).

=> #<XML::Schema:0x365c54>
irb(main):005:0> xml.validate sch
error -- found validity error: no root element

Instead of validate, you need to pass your schema to validate_schema:

sch = XML::Schema.from_string(File.read('shiporder.xsd'))
# => #<XML::Schema:0xb7f098f0>

xml.validate_schema(sch)
# => true

Hope that helps,
Ross

···

On Tue, 2006-10-03 at 06:01 +0900, Peter Fitzgibbons wrote:

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Ross Bamford wrote:

Problem here - The argument to XML::Document.new is interpreted as the
XML version to use, rather than as a file to read (notice the XML
version is your filename).

POLS violation? Seriously, has anyone of you ever seen a XML document of
a version other than 1.0 in the wild, or felt a need to write one?

David Vallner

Yeah, I agree it's pretty confusing, but for 0.3.8 we tried to keep the
API fairly stable. There's a good sized list of small changes to make
and bugs to fix for 0.4.0... Someone (me I guess) just has to get the
time to make them :wink:

···

On Sat, 2006-10-07 at 05:34 +0900, David Vallner wrote:

Ross Bamford wrote:
> Problem here - The argument to XML::Document.new is interpreted as the
> XML version to use, rather than as a file to read (notice the XML
> version is your filename).

POLS violation? Seriously, has anyone of you ever seen a XML document of
a version other than 1.0 in the wild, or felt a need to write one?

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Ross Bamford wrote:

Someone (me I guess) just has to get the
time to make them :wink:

Ah yes, the usual :stuck_out_tongue_winking_eye:

Hey, at least you're in the authority to change them. I should start my
own pet project one of these days as stress relief after having to fix
the umptieth bug someone caused by copy / pasting boilerplate code
around without bothering to check if, let's say, the form validation
he's using makes any sense whatsoever after he goes on and changes all
fields in the form without being able to bitchslap said person.

*ponders joining IntelliJ IDEA and Ruby syntax highlighting in unholy
matrimony*

David Vallner