Generate Ruby Classes from XSD - ruby

Is there a way to generate Ruby classes (maybe even ActiveResource classes) from an XSD so that they contain a way to serialize the classes to xml valid for the initial XSD?
I know that soap4r has xsd2ruby but it appears that the generated ruby classes cannot be easily serialized to xml.

Shameless self promotion (hope this is okay on stackoverflow) but I'm working on an open source project to do just that
Its still a work in progress (feel free to send patches) but the ultimate goal is to convert XSD to/from Ruby classes (which it does now) and convert XML conforming to that XSD to/from instances of those classes.

Though this was asked a while ago, I came across a solution and thought it might help folks in the future.
My need was similar. I have a .xsd from a colleague and would like to generate a class file from it. My hope is that I'll be able to easily marshall the object and pass it to his RESTful end-point, where his Java server will unmarshall the payload and dynamically build the object on his side with no additional effort.
The solution I found was to get the soap4r from https://github.com/rubyjedi/soap4r. I made the two *.rb files in the bin directory executable and then ran:
bin/xsd2ruby.rb --xsd <source>.xsd --classdef <filename_prefix>
This generated a new file with each of the xsd:complexType implemented as a class. All other complex type were also generated with the correct inheritance relationships and all xsd:element was defined as an instance variable and a class initializer also defined.
Running xsd2ruby.rb by itself yielded the options:
~/src/test/soap4r:bin/xsd2ruby.rb
Usage: bin/xsd2ruby.rb --xsd xsd_location [options]
xsd_location: filename or URL
Example:
bin/xsd2ruby.rb --xsd myapp.xsd --classdef foo
Options:
--xsd xsd_location
--classdef [filenameprefix]
--mapping_registry
--mapper
--module_path [Module::Path::Name]
--force
--quiet
For the sake of completeness, I extended my class with the following (this is a "Prospect" class):
class Prospect
include Enumerable
def each(&block)
self.instance_variables.collect{|v| (v.gsub /#/, '').to_sym }.each(&block)
end
end
This let me use it as the body of an Net::HTTP::Post request.
To the question of a free to_xml: I haven't found it. The ruby Object comes with a to_yaml and to_json out of the box, but I've not found any simple conversion to XML. So it came down to a roll my own "to_xml".
Hope this helps.

It appears that this might work.
require 'xsd/mapping'
XSD::Mapping.obj2xml(xsdBasedObject)

Related

Generate Ruby classes from XML Schema Definition (XSD)

What is the preferred way to build a Ruby API for writing XML files based on an existing XSD file?
I know there is xsd2ruby from soap4r, but the generated classes are not very useful, IMHO:
The generated initializer has lots of parameters, one for each attribute. I would like to have a Hash param instead
For restrictions (length, enumeration, patterns, ...) no code is generated
What do you use today? Having generated Ruby classes for a complex XSD file would be very helpful.

How I can modularize Rails model?

I'm implementing several classes which does not have data by itself, just logics. These classes implements access control policy to date which depends on several parameters taken from data from other models.
I initially try to find answer to "Where to store such classes?" here, and the answer was apps/models directory. That's ok, but I like to clearly separate these classes from ActiveRecord inherited classes in hierarchy, both as file and class.
So, I created classes inside Logic module, like Logic::EvaluationLogic or Logic::PhaseLogic. I also wanted to have constants which passed between these logics. I prefer to place these constants into Logic module too. Thus, I implemented like this:
# in logic/phase_logic.rb
module Logic
PHASE_INITIAL = 0
PHASE_MIDDLE = 1000
class PhaseLogic
def self.some_phase_control_code
end
end
end
# in logic/evaluation_logic.rb
module Logic
class EvaluationLogic
def self.some_other_code
Logic::PhaseLogic.self.some_phase_control_code(Logic::PHASE_INITIAL)
end
end
end
Now, it work just fine with rspec (It passes tests I wrote without issues), but not with development server, since it can't find the Logic::PHASE_INITIAL constant.
I suspect it's related to the mismatch of the autoloading scheme of Rails and what I wanted to do. I tried to tweak rails, but no luck, ended-up with eliminating module Logic wrap.
Now the question I want to ask: How I can organize these classes with Rails?
I'm using 3.2.1 at this moment.
Posted a follow-up question "How I can organize namespace of classes in app/modules with rails?"
I am not sure whether I really understand your classes, but couldn't you create a Logic module or (I would rather do this:) PhaseLogic and EvaluationLogic objects in /lib directory?
It is not said that "Model" is always descendant of ActiveRecord. If the object belongs to "business logic" then it is a model. You can have models which do not touch database in any way. So, if your classes are "business objects", place them in 'app/models' and use like any other model.
Another question is whether you should use inheritance or modules - but I would rather think about including a module in PhaseLogic, and not about defining PhaseLogic in a module. Of course, all this depends heavily on the intended role of your objects.
Because in Ruby the class of object is not important, you do not need to use inheritance. If you want to 'plug' the logic objects into other objects, just take care that all '*Logic' classes have the required methods. I know that all I said is very vague, but I think I cannot give you some more concrete suggestions without knowing more about the role of these objects.
Ah, and one more thing!
If you find yourself fighting with Rails class autoloading, just use the old require "lib/logic.rb" in all the classes where you are using Logic::PHASE_INITIAL constants.
In this case I suppose that your problem was caused by different order of loading. The logic/evaluation_logic.rb has been loaded before logic/phase_logic.rb. The problem may disappear if you create logic.rb somewhere, where class autoloading can find it, and define these constants in that file.
Don't name your classes or modules Logic use specific names. Start with extracting logic into separate classes and then try to break them into smaller ones. Use namespaces to distinguish them from each other in lib folder, after this steps you would be able to extract some logic parts to separate gems and reduce codebase and complexity of application. Also take a look into presenter pattern.

Dynamically Generating ORM Classes

I'm working on a Sinatra-based project that uses the Datamapper ORM. I'd like to be able to define criteria for the DM validations in an external YAML file so that less-experienced users of the system can easily tweak the setup. I have this working pretty well as a proof-of-concept, but I suspect there could be a much easier or a least less processor-intensive way to approach this.
Right now, the script loads the YAML file and generates the DM classes with a series of eval statements (I know this already places me on thin ice). The problem is that this process has to happen with every request. My bright idea is to check the YAML for changes, regenerate the classes and export to static source if changes are detected, and include the static files if no changes are detected.
This is proving more difficult than I anticipated because exporting code blocks to strings for serialization isn't as trivial as I expected.
Is this ridiculous? Am I approaching this in an entirely wrong-headed way?
I'm new to Ruby and the world of ORMs, so please forgive my ignorance.
Thanks!
DM validations in an external YAML file so that less-experienced users of the system can easily tweak the setup
A DSL for a DSL. Not having seen your YAML I still wonder how much easier than the DM Validations it really can get?
require 'dm-validations'
class User
include DataMapper::Resource
property :name, String
# Manual validation
validates_length_of :name, :max => 42
# Auto-validation
property :bio, Text, :length => 100..500
end
Instead of going for YAML I would provide the less-experienced users with a couple of relevant validation examples and possibly also a short guideline based on the dm-validations documentation.
It does seem a little crazy to go and put everything in YAML, as that's only a shade easier than writing the validations in Ruby. What you could do is make a DSL in Ruby that makes defining validations much easier, then expose that to your users instead of the whole class.

Implementing a DSL in Ruby for generating domain specific XML

I'd like to implement a DSL in Ruby for generating domain specific XML documents (i.e. XML which conforms to a specific schema). I can use e.g. Builder to write the XML in Ruby, which is already a great improvement on writing the XML manually, but I'd also like:
convenience methods that would generate a whole bunch of XML for me
and possibly a way to restrict the generator to a schema (not necessarily an XSD or a DTD, but the implementation could possibly generate only certain tags)
So my plan at the moment is to extend Builder with the convenience methods and ignore the schema restriction side of things for now.
My questions to the community are does this sounds like a reasonable plan, and more importantly, are there any DSLs out there that extend Builder in some fashion that I could use for inspiration.
Unfortunately googling for ruby, xml, builder, extend, dsl, ... doesn't return very interesting results.
I don't know if it uses Builder, but haml is certainly worth looking.
I also found this article wich mentions many more, of those, probably Markaby is the closest to your idea, but the last commit on github is from 2008. Surely looking at _why's code should be entertaining.

What is the opposite of JAXB? i.e. generating XML FROM classes?

I am currently designing a solution to a problem I have. I need to dynamically generate an XML file on the fly using Java objects, in the same way JAXB generates Java classes from XML files, however the opposite direction. Is there something out there already like this?
Alternatively, a way in which one could 'save' a state of java classes.
The goal I am working towards is a dynamically changing GUI, where a user can redesign their GUI in the same way you can with iGoogle.
You already have the answer. It's JAXB! You can annotate your classes and then have JAXB marshal them to XML (and back) without the need to create an XML schema first.
Look at https://jaxb.dev.java.net/tutorial/section_6_1-JAXB-Annotations.html#JAXB%20Annotations to get started.
I don't know, if this is exactly what you're looking for, but there's the java.beans.XMLEncoder:
XMLEncoder enc = new XMLEncoder(new FileOutputStream(file));
enc.writeObject(obj);
enc.close();
The result can then be loaded by XMLDecoder:
XMLDecoder dec = new XMLDecoder(new FileInputStream(file));
Object obj = dec.readObject();
dec.close();
"generate xml from java objects:"
try xtream.
Here's what is said on the tin:
No mappings required. Most objects can be serialized without need for specifying mappings.
Requires no modifications to objects.
Full object graph support
For saving java object state:
Serialization is the way to do this in Java

Resources