4Suite has RELAX NG support based on a bundling of Eric van der Vlists's XVIF implementation.
First of all, you can use 4xml for RELAX NG validation with the --rng flag. For instance, take the following RELAX NG schema (rng-tut3.rng):
<element name="addressBook" xmlns="http://relaxng.org/ns/structure/1.0"> <zeroOrMore> <element name="card"> <element name="name"> <text/> </element> <element name="email"> <text/> </element> </element> </zeroOrMore> </element>
The following document (rng-tut1.xml) is valid against the schema:
<addressBook>
<card>
<name>John Smith</name>
<email>js@example.com</email>
</card>
<card>
<name>Fred Bloggs</name>
<email>fb@example.net</email>
</card>
</addressBook>
As you can check as follows:
$ 4xml --rng=rng-tut3.rng rng-tut1.xml
<?xml version="1.0" encoding="utf-8"?>
<addressBook>
<card>
<name>John Smith</name>
<email>js@example.com</email>
</card>
<card>
<name>Fred Bloggs</name>
<email>fb@example.net</email>
</card>
</addressBook>
Since it passes the schema, 4xml continues normal operation, re-serializing the XML back to stdout.
The following document (rng-tut7.xml) is not valid against the schema:
<addressBook>i
<card>
<givenName>John</givenName>
<familyName>Smith</familyName>
<email>js@example.com</email>
</card>
<card>
<name>Fred Bloggs</name>
<email>fb@example.net</email>
</card>
</addressBook>
Which you can check as follows:
$ 4xml --rng=rng-tut7.rng rng-tut1.xml
Traceback (most recent call last):
File "/home/uogbuji/lib/python2.2/site-packages/Ft/Share/Bin/4xml", line 5, in ?
XmlCommandLineApp().run()
File "/home/uogbuji/lib/python2.2/site-packages/Ft/Lib/CommandLine/CommandLineApp.py", line 90, in run
cmd.run_command(self.authenticationFunction)
File "/home/uogbuji/lib/python2.2/site-packages/Ft/Lib/CommandLine/Command.py", line 83, in run_command
self.function(self.clOptions, self.clArguments)
File "/home/uogbuji/lib/python2.2/site-packages/Ft/Xml/_4xml.py", line 89, in Run
raise RngInvalid(result)
Ft.Xml.Xvif.RngInvalid: _Pattern Empty, no content expected,
node <cElement at 0x838d7f4: name u'card', 0 attributes, 7 children>
The exception is for the invalid pattern.
You can also access validation through the Python API using the new Ft.Xml.Xvif.RelaxNgValidator class. For example:
from Ft.Xml.Xvif import RelaxNgValidator
from Ft.Xml import InputSource
from Ft.Lib import Uri
factory = InputSource.DefaultFactory
rng_uri = Uri.OsPathToUri("rng-tut3.rng", attemptAbsolute=1)
src_uri = Uri.OsPathToUri("rng-tut1.xml", attemptAbsolute=1)
rng_isrc = factory.fromUri(rng_uri)
src_isrc = factory.fromUri(src_uri)
validator = RelaxNgValidator(rng_isrc)
result = validator.isValid(src_isrc)
if result:
print "Valid"
else:
print "Invalid"
The isValid() method returns a 1 or 0 for validity. To get the actual structure returned by the validator, use the validate() method instead. This structure can easily be turned into an exception object. The following variation prints "Valid" if valid, and raises an exception if not:
from Ft.Xml.Xvif import RelaxNgValidator, RngInvalid
from Ft.Xml import InputSource
factory = InputSource.DefaultFactory
from Ft.Lib import Uri
factory = InputSource.DefaultFactory
rng_uri = Uri.OsPathToUri("rng-tut3.rng", attemptAbsolute=1)
src_uri = Uri.OsPathToUri("rng-tut1.xml", attemptAbsolute=1)
rng_isrc = factory.fromUri(rng_uri)
src_isrc = factory.fromUri(src_uri)
validator = RelaxNgValidator(rng_isrc)
result = validator.validate(src_isrc)
if result.nullable():
print "Valid"
else:
raise RngInvalid(result)
If you want to use the validation error message without raising an exception:
#Set-up as above
result = validator.validate(src_isrc)
if result.nullable():
print "Valid"
else:
print result.msg
Note: The original announcement of XVIF support is now out of date: the APIs have changed a bit.
For more on RELAX NG in general, see The official RELAX NG tutorial.
For more on XVIF, see this follow-up by Eric.
I use 4xml's --rng option in examples in my article on Examplotron
Comments
The link "follow-up by Eric" at the bottom of the page is wrong. I think, you meant this one:
http://lists.fourthought.com/pipermail/4suite/2002-October/004432.html
