Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to dynamically create XSL file based on XSD file

Tags:

xslt

I have a project where I need to convert a XML file to CSV file and vice versa. I can't use a single XSL file because, there are different XML and CSV formats. So, I am just wondering if there is any way (any tool or editors or any APIs) to create XSL file based on XSD file.

I am also open to any other suggestions too (I believe I can't avoid XSL because in the future I might be asked to convert to different formats such as pdf, html etc)

like image 853
karanece Avatar asked Feb 13 '12 00:02

karanece


People also ask

Can we generate XML from XSD?

To create an XML file from an XSD file: Right-click the XML Documents folder in your data development project, and select New > XML. The New XML File wizard opens.

Can we convert XML to XSL?

The standard way to transform XML data into other formats is by Extensible Stylesheet Language Transformations (XSLT). You can use the built-in XSLTRANSFORM function to convert XML documents into HTML, plain text, or different XML schemas. XSLT uses stylesheets to convert XML into other data formats.

Is there any benefit of converting XML to XSLT?

XSLT is commonly used to convert XML to HTML, but can also be used to transform XML documents that comply with one XML schema into documents that comply with another schema. XSLT can also be used to convert XML data into unrelated formats, like comma-delimited text or formatting languages such as troff.


2 Answers

I realise that this was asked and answered a good 3 years ago, but I came across it while asking myself the same question. The short answer is yes, of course, because you are simply converting one type of XML to another (albeit with some structural and syntax changes). I saw this: https://www.oxygenxml.com/archives/xsl-list/200807/msg00601.html - which outlines a basic implementation as proof of concept, and I used that as a starting point to create the following XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes" method="xml" /> 

    <xsl:template match="/">
        <xsl:comment> ............................................................................................... </xsl:comment>

        <xsl:element name="xsl:stylesheet">
            <xsl:namespace name="xsl" select="'http://www.w3.org/1999/XSL/Transform'" /> <xsl:attribute name="version" select="'1.0'" /> 

            <xsl:element name="xsl:output">
                <xsl:attribute name="indent" select="'yes'" />
                <xsl:attribute name="method" select="'xml'" />
            </xsl:element>

            <xsl:comment> ............................................................................................... </xsl:comment>
            <xsl:comment>                                                                                                 </xsl:comment>
            <xsl:comment> ............................................................................................... </xsl:comment>

            <xsl:element name="xsl:template">
                <xsl:attribute name="match" select="'/'" />
                <xsl:element name="xsl:apply-templates">
                    <xsl:attribute name="select" select="'node()'" />
                </xsl:element>
            </xsl:element>

            <xsl:comment> ............................................................................................... </xsl:comment>

            <xsl:element name="xsl:template">
                <xsl:attribute name="match" select="'node()'" />
                <xsl:element name="xsl:if">
                    <xsl:attribute name="test" select="'.!=&apos;&apos;'" />
                    <xsl:element name="xsl:copy"></xsl:element>
                </xsl:element>
            </xsl:element>

            <xsl:comment> ............................................................................................... </xsl:comment>
            <xsl:comment>                                                                                                 </xsl:comment>
            <xsl:comment> ............................................................................................... </xsl:comment>

            <xsl:apply-templates /> 
        </xsl:element>

        <xsl:comment> ............................................................................................... </xsl:comment>
    </xsl:template>

    <xsl:template match="xs:complexType[@name]">
        <xsl:element name="xsl:template">
            <xsl:attribute name="match" select="@name" />
            <xsl:apply-templates /> 
        </xsl:element>
        <xsl:comment> ............................................................................................... </xsl:comment>
    </xsl:template>

    <xsl:template match="xs:complexType[not(@*)]">
        <xsl:element name="xsl:apply-templates">
            <xsl:attribute name="select" select="@name" />
            <xsl:apply-templates /> 
        </xsl:element>
    </xsl:template>

    <!-- xsl:template match="xs:simpleType[@name]">
        <xsl:element name="xsl:apply-templates">
            <xsl:attribute name="select" select="@name" />
            <xsl:apply-templates /> 
        </xsl:element>
    </xsl:template -->

    <xsl:template match="xs:sequence">
        <xsl:element name="xsl:copy">
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="xs:element[@name]">
        <xsl:element name="xsl:apply-templates">
            <xsl:attribute name="select" select="@name" />
        </xsl:element>
    </xsl:template>

    <xsl:template match="xs:attribute">
        <xsl:element name="xsl:apply-templates">
            <xsl:attribute name="select" select="concat( '@', @name )" />
        </xsl:element>
    </xsl:template>

    <!-- xsl:template match="xs:element[@name]">
        <xsl:text>&#xA;&#xA;</xsl:text>
        <xsl:element name="xsl:template">
            <xsl:attribute name="match" select="@name" /> 
            <xsl:text>&#xA;</xsl:text>
            <xsl:comment>
                auto generated stub for element <xsl:value-of select="@name" /> 
            </xsl:comment>
            <xsl:text>&#xA;</xsl:text>
        </xsl:element>
        <xsl:apply-templates /> 
    </xsl:template -->

    <xsl:template match="text()" />

</xsl:stylesheet>

Note the use of xsl:element to create the XSLT tags and creating select and match attributes, the quoting in selects and escaping. The comment blocks are there to visually break up the root of the document (make it more readable) but serve no other purpose. Also, this requires an XSLT 2.0 processor. xsltproc users need not apply.

As per the previous responses, you'll have to modify it in varying degrees for your use case. I made this so that I could quickly create an accurate skeleton from which I could build out a useful XSLT document, while automating the tedious groundwork.

Naturally, I've just spent hours developing and testing something that at this point I probably could have done faster by hand with grep, but at least it was interesting. Hope this helps someone and improvements are welcome.

like image 169
Kevin Teljeur Avatar answered Nov 15 '22 11:11

Kevin Teljeur


An XSD file describes the structure of a valid XML file that conforms to certain rules. An XSLT file describes how to transform an input XML document to some output form, which may or may not be XML. It is not possible to deduce an XSL transformation from an XSD file as they address completely different aspects of XML.

In other words, an XSD allows you to confirm that an XML document adheres to a predefined set of constraints, but says nothing about what to do with the XML, or how to transform it to something else.

like image 40
Jim Garrison Avatar answered Nov 15 '22 10:11

Jim Garrison