[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Creating Ruby Classes from XSD?

jgbailey

2/23/2006 5:13:00 PM

NET ships with a tool that will generate classes directly from an XML
schema (XSD) file. Does the Ruby standard library have anything similar?
It's a great tool on the .NET side, and I bet Ruby could do it even better,
if not.
13 Answers

Logan Capaldo

2/23/2006 5:33:00 PM

0


On Feb 23, 2006, at 12:12 PM, Justin Bailey wrote:

> .NET ships with a tool that will generate classes directly from an XML
> schema (XSD) file. Does the Ruby standard library have anything
> similar?
> It's a great tool on the .NET side, and I bet Ruby could do it even
> better,
> if not.

Ok, I'm going to be honest and say first I've never had occasion to
use this tool. But I'm wondering what exactly is the point? Ruby's
syntax is much less verbose than XML.
Why would you want to type this:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema...
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>

When you can do one of these:
class Shipto < Struct.new(:name, :address, :city, :country)
end

class Item < Struct.new(:orderid, :title, :note, :quantity, :price)
end

class Shipment < Struct.new(:shipto, :item)
end

shipments = []

I may have mangled some of the XSD, I'm admitedly not familiar with
it, but generating classes froma schema seems rife with problems




jgbailey

2/23/2006 5:48:00 PM

0

Brian Moelk

2/23/2006 6:56:00 PM

0

> .NET ships with a tool that will generate classes directly from an XML
> schema (XSD) file. Does the Ruby standard library have anything similar?
> It's a great tool on the .NET side, and I bet Ruby could do it even
better,
> if not.

This may be interesting to you: http://rubyforge.org/projec...

I haven't used it, but the author discussed it at a recent RUG meeting and
it interested me at the time.

-Brian



Henrik Martensson

2/23/2006 10:59:00 PM

0

On Thu, 2006-02-23 at 18:32, Logan Capaldo wrote:
<snip>
> Ok, I'm going to be honest and say first I've never had occasion to
> use this tool. But I'm wondering what exactly is the point? Ruby's
> syntax is much less verbose than XML.
> Why would you want to type this:
<snipped a W3C Schema>
> When you can do one of these:
<snipped Ruby class definitions
>
> I may have mangled some of the XSD, I'm admitedly not familiar with
> it, but generating classes froma schema seems rife with problems
>

The basic idea is that if you have a schema specification, you can
generate classes for whatever language you want, and the applications
that use them will all understand the same data formats.

Unfortunately, the idea is flawed. You are quite right. There isn't much
of a point. Building classes directly from a data format specification
makes the application using the classes tightly coupled to the data
format.

In most cases it is better to work with a generic XML parsing API,
wether it is REXML, DOM, SAX, or something else. It makes it a lot
easier to write robust applications.

I have worked with SGML/XML for a long time. I like XML, but not for
everything. One of the things that attracted me to Ruby is that it has
to a large part escaped the "XML for everything" craze that permeats
Java, and to some extent .NET.


/Henrik

--
http://kallokain.blo... - Blogging from the trenches of software
development
http://www.henrikmarte... - Reflections on software development
http://testunitxml.ruby... - The Test::Unit::XML Home Page
http://declan.ruby... - The Declan Home Page





Geoff Lane

2/24/2006 2:09:00 AM

0


Check out SOAP4R.
It includes xsd2ruby and wsdl2ruby tools. They don't come in the
standard distribution I don't think.

As for everyone wanting to know why XSD?

XSD allows you to define language-independent schemas that can be
consumed by multiple languages. If you define a Schema up front when
you do SOAP document literal services, you can get full validation
before your service is called.

On Feb 23, 2006, at 11:12 AM, Justin Bailey wrote:

> .NET ships with a tool that will generate classes directly from an XML
> schema (XSD) file. Does the Ruby standard library have anything
> similar?
> It's a great tool on the .NET side, and I bet Ruby could do it even
> better,
> if not.

--
Geoff Lane <geoff@zorched.net>





Dave Cantrell

2/24/2006 4:43:00 AM

0

Henrik Martensson wrote:
> Unfortunately, the idea is flawed. You are quite right. There isn't much
> of a point. Building classes directly from a data format specification
> makes the application using the classes tightly coupled to the data
> format.

ActiveRecord?

I've never used Rails and have been in limbo for 2 weeks learning Ruby
due to work swampage, but it seems from everything I read that
ActiveRecord does exactly what you are coming out against, and does it
very well.

-dave


Geoff Lane

2/24/2006 1:28:00 PM

0


On Feb 23, 2006, at 4:59 PM, Henrik Martensson wrote:

> On Thu, 2006-02-23 at 18:32, Logan Capaldo wrote:
> <snip>
>> Ok, I'm going to be honest and say first I've never had occasion to
>> use this tool. But I'm wondering what exactly is the point? Ruby's
>> syntax is much less verbose than XML.
>> Why would you want to type this:
> <snipped a W3C Schema>
>> When you can do one of these:
> <snipped Ruby class definitions
>>
>> I may have mangled some of the XSD, I'm admitedly not familiar with
>> it, but generating classes froma schema seems rife with problems
>>
>
> The basic idea is that if you have a schema specification, you can
> generate classes for whatever language you want, and the applications
> that use them will all understand the same data formats.
>
> <snip> Building classes directly from a data format specification
> makes the application using the classes tightly coupled to the data
> format.

Yep, that's the exact idea. You don't only want to be tightly-coupled
to the data specification, you want it to be EXACTLY the same. The
most common place this is used is in SOAP Web Service design. It's
often called contract first or schema first design. It's not a bad
thing to be tightly coupled to your data at that point because the
whole idea is to be able to interoperate with an existing service.
This is all about sharing, and it's nice to make things easy and
language-neutral when you're going to share. (Cue up Mr. Rogers theme
music.)

XSD schema (for all of its imperfections) has the ability to specify
constraints on the data that help validate it. Up front your service
can define things like:

(pseudo-XSD)
US Address:
Street1 = required
Street2 = optional
City = required
State = [A-Z]{2}
USZip = [0-9]{5}(-[0-9]{4})?

Those kinds of constraints can be done in code, but no language I
know of can make an interface to a method that explicit.


--
Geoff Lane <geoff@zorched.net>





Henrik Martensson

2/24/2006 4:29:00 PM

0

On Fri, 2006-02-24 at 05:42, Dave Cantrell wrote:
> Henrik Martensson wrote:
> > Unfortunately, the idea is flawed. You are quite right. There isn't much
> > of a point. Building classes directly from a data format specification
> > makes the application using the classes tightly coupled to the data
> > format.
>
> ActiveRecord?
>
> I've never used Rails and have been in limbo for 2 weeks learning Ruby
> due to work swampage, but it seems from everything I read that
> ActiveRecord does exactly what you are coming out against, and does it
> very well.

No, I have nothing against ORM tools. ActiveRecord, (which I must
confess I haven't used, just poked at while playing with Rails a while
ago,) provides an interface between a data source layer and a business
layer, and that is fine. Couldn't manage relational databases without
ORM. (Still, there are XML databases that you can query with XPath or
XQuery, and get an XML message from when they reply. This approach does
have practical problems (like abysmal performance), but when you are
dealing with hierarchical information it is a pretty neat approach.)

An ORM tool provides a way to make objects persistent and bridges the
data source layer and the business layer in an application. This is
good.

A schema to code generator creates a tight coupling between a document
(or 'message') format and business logic. It is often used in client
applications to generate code that couples the application tightly to a
data format _owned_by_somebody_else_. This is bad.

If I build a SOAP service, and you build a client and generate classes
from the WSDL I provide, then your application will break every time I
change the data format.

On the other hand, if I offer a REST service, and you build an
application that uses LibXML to mine the messages for the information
you need, then I can add new stuff to the dataformat without breaking
your application.

Consider an XML editor. An XML editor uses an internal representation of
XML documents that is generic. For example, XMetaL uses DOM, and you can
use the editor to edit XHTML, DocBook, XSEIF, TIM, TEDD, TEI, or
whatever you like.

If the editor had been written using a code generator to map from a
schema to an internal representation that is specific to that one
format, then the editor would only have been able to handle one format.
For example, you would get an XHTML editor that could not handle DocBook
or TEI. If you wanted to use a new format, you would need a new editor.
(Plenty of editors are built that way. It is still not a good idea.)

/Henrik

--
http://kallokain.blo... - Blogging from the trenches of software
development
http://www.henrikmarte... - Reflections on software development
http://testunitxml.ruby... - The Test::Unit::XML Home Page
http://declan.ruby... - The Declan Home Page





Henrik Martensson

2/24/2006 4:59:00 PM

0

On Fri, 2006-02-24 at 14:27, Geoffrey Lane wrote:
>
> Yep, that's the exact idea. You don't only want to be tightly-coupled
> to the data specification, you want it to be EXACTLY the same. The
> most common place this is used is in SOAP Web Service design. It's
> often called contract first or schema first design. It's not a bad
> thing to be tightly coupled to your data at that point because the
> whole idea is to be able to interoperate with an existing service.

My point is that you are tightly coupled to somebody elses data. This
means your application is very vulnerable.

SOAP does have a lot of problems because of this. REST offers a more
flexible alternative.

Tight coupling isn't necessarily bad - a lot of the time nothing
changes, and then everything works. On the other hand, why take the risk
if there is no great benefit? Sometimes things do change. then things
get expensive.

> This is all about sharing, and it's nice to make things easy and
> language-neutral when you're going to share. (Cue up Mr. Rogers theme
> music.)

Also, when sharing, it is important to be flexible. In this case, the
flexibility doesn't really cost you anything, because using a generic
data model is just as easy as using a customized one. Sometimes it is
even easier.

>
> XSD schema (for all of its imperfections) has the ability to specify
> constraints on the data that help validate it. Up front your service
> can define things like:
>
> (pseudo-XSD)
> US Address:
> Street1 = required
> Street2 = optional
> City = required
> State = [A-Z]{2}
> USZip = [0-9]{5}(-[0-9]{4})?
>
> Those kinds of constraints can be done in code, but no language I
> know of can make an interface to a method that explicit.

You can do it in W3C XML Schema and in RELAX NG. In principle, you can
do it with NOTATIONs in a DTD, if only two people could ever agree on
what a NOTATION declaration means.

I do like your example. Suppose the addresses are in a customer
database, and the company that owns it expands its operations to Europe.
They will then need to extend their data format so that they can handle
the addresses of European customers, so they add a country field, and a
zip code field that isn't U.S. specific. While they're at it, they add
fields for phone number, fax, mobile, email, and web site. Seing that
the Street2 field isn't very useful, they remove it.

If you have built a client in the U.S. that queries the database, and
maps the result to an object model generated from a schema, your
application will now go KABLOINK! If your application uses REXML, SAX or
DOM, it can just ignore the extra information and keep working smoothly.

/Henrik

--
http://kallokain.blo... - Blogging from the trenches of software
development
http://www.henrikmarte... - Reflections on software development
http://testunitxml.ruby... - The Test::Unit::XML Home Page
http://declan.ruby... - The Declan Home Page





netghost

2/24/2006 5:16:00 PM

0

I've actually found that you don't usually want to use the xml
directly. Most of the time, data I get in xml was formed by a
commitee, and they didn't have anyone who was familiar with either XSDs
or structuring information in xml well.

Roughly, I have a base class that has this method in it:

def self::xml_attr(name, path, type, options={})
class_eval do
define_method(name) do
# Get node or attribute
node = REXML::XPath.first(@root, path)
#Convert to a typed value
value = self.class.parse_node(node, type, options) if
node
end
end
once(name) unless options[:cache] == false
end

parse_node manages known types of nodes that I define elsewhere like
strings, floats, dates, arrays, and classes. Like I said, that's
roughly what I use because that's a little old, but this way you can
build model objects similar to ActiveRecord or Og, and map them to the
appropriate xml bits with XPath. I've found that it's pretty flexible
and only comes in around 70 lines of code ;)

Someone posted a nearly identical solution on RubyGarden, but I can't
remember where now. I can pull it up if you're interested.
.adam