in reply to Automatically creating data validation module from XSD

My first thought would be to try and tackle this with XSLT. As XSD is XML, and you're trying to convert XSD/XML to another form (source code, which is just plain text), this sounds like a job for a templating system that can process XML as input – even though I've never used XSLT to convert XML to plain text.

I feel like taking a stab at it, but just a dry spec with no examples is much too dry for me. So I concur with nferraz: can you offer us a real world XSD file and the Perl module you created from it by hand? That'll give me something to aim for.

If it works, it can still be used as a working example to rework it into a Perl script, or module.

  • Comment on Re: Automatically creating data validation module from XSD

Replies are listed 'Best First'.
Re^2: Automatically creating data validation module from XSD
by bart (Canon) on Aug 11, 2007 at 22:33 UTC
    I've made a first test XSL file:
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema" > <xsl:output method="text"/> <xsl:template match="xsd:simpleType"> sub <xsl:value-of select="@name" /> { <xsl:for-each select="xsd:annotation/xsd:documentation"># <xsl:val +ue-of select="normalize-space(.)" /></xsl:for-each> my($class, $value) = @_; return FALSE if _is_null($value); return <xsl:for-each select="xsd:restriction"><xsl:value-of select +="replace(@base,':', '_')" />($value) and <xsl:apply-templates mode=" +restriction" select="*"/>TRUE;</xsl:for-each> } </xsl:template> <xsl:template mode="restriction" match="xsd:minInclusive">$value &gt;= + <xsl:value-of select="@value" /> and </xsl:template> <xsl:template mode="restriction" match="xsd:minExclusive">$value &gt; +<xsl:value-of select="@value" /> and </xsl:template> <xsl:template mode="restriction" match="xsd:maxInclusive">$value &lt;= + <xsl:value-of select="@value" /> and </xsl:template> <xsl:template mode="restriction" match="xsd:maxExclusive">$value &lt; +<xsl:value-of select="@value" /> and </xsl:template> </xsl:stylesheet>
    It converts the sample from brian's root node, after I wrapped in it an "xsd:schema" top level element, just as in the XSD file he linked to, using Saxon8, into:
    sub longitudeType { # The longitude of the point. Decimal degrees, WGS84 datum. my($class, $value) = @_; return FALSE if _is_null($value); return xsd_decimal($value) and $value >= -180.0 and $value < 180.0 + and TRUE; }
    What do you think, brian? Is this close?

    It doesn't work in XML Notepad, because of the replace (which replaces the colon with an underscore). Without it, it works in MS XML Notepad, too — except for the missing substitution, of course.

    For kicks, I've processed the original XSD file this way, and (apart from some junk from those element that are now not handled in the XSD file) I get this:

    This is fun.

    p.s. I used TRUE and FALSE as booleans for readability. You can always replace them with 1 and 0, but I would prefer constants.

    Update brian asked how hard it is to extend to process other types too, in particular, fixType (enumeration). That turned out to be an addition of a few extra lines. I've also done a few extra modifications so it puts a package declaration at the top, a "1;" at the bottom, and suppression of the junk. The result is here:

      It doesn't work in XML Notepad, because of the replace

      MS has only poor support for EXSLT which also is the case for its string extensions of XPath 1.0 (replace).

      Standard XPath 1.0 offers translate (somewhat like tr in Perl). For your purpose just do a s/replace/translate/ and even limited renderer like XML Notepad are satisfied. (tested)