有没有办法基于XSD文件动态创建XSL文件

时间:2012-02-13 00:18:07

标签: xslt

我有一个项目需要将XML文件转换为CSV文件,反之亦然。我不能使用单个XSL文件,因为有不同的XML和CSV格式。所以,我只是想知道是否有任何方法(任何工具或编辑器或任何API)来创建基于XSD文件的XSL文件。

我也对任何其他建议持开放态度(我相信我无法避免XSL,因为将来我可能会被要求转换为不同格式,例如pdf,html等)

5 个答案:

答案 0 :(得分:4)

我意识到这是3年前被问到并回答的很好,但我在问自己同样的问题时遇到了它。简而言之,答案是肯定的,因为您只是将一种类型的XML转换为另一种类型(尽管有一些结构和语法更改)。我看到了这个:https://www.oxygenxml.com/archives/xsl-list/200807/msg00601.html - 它概述了一个基本实现作为概念证明,我用它作为创建以下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>

请注意使用xsl:element创建XSLT标记并创建selectmatch属性,引用选择和转义。 comment块可以直观地分解文档的根目录(使其更具可读性),但不能用于其他目的。此外,这需要XSLT 2.0处理器。 xsltproc用户无需申请。

根据之前的回复,您必须根据您的使用情况对其进行不同程度的修改。我做了这个,这样我就可以快速创建一个准确的骨架,从中我可以构建一个有用的XSLT文档,同时自动化繁琐的基础工作。

当然,我只是花了几个小时开发和测试一些东西,在这一点上我可能用grep手动完成,但至少它很有趣。希望这有助于某人,并欢迎改进。

答案 1 :(得分:3)

XSD文件描述符合某些规则的有效XML文件的结构。 XSLT文件描述了如何将输入XML文档转换为某种输出形式,可能是也可能不是XML。无法从XSD文件中推断出XSL转换,因为它们解决了XML的完全不同方面。

换句话说,XSD允许您确认XML文档符合一组预定义的约束,但没有说明如何处理XML,或者如何将其转换为其他内容。

答案 2 :(得分:1)

与您的问题中的断言相反,您可以实际使用单个XSLT文件从通用CSV转换为XML。请参阅:Kernow's converter

答案 3 :(得分:1)

就像Jim Garrison所说,XSD和XSLT之间没有简单的映射。但它们都是XML格式,因此将一个映射到另一个并非不可能。根据格式的一般结构,如果结构足够简单,也可以编写通用XSLT将任何XML直接映射到CSV。

您必须提供一些XML数据示例,XSD和预期结果。

答案 4 :(得分:0)

答案是-是。可以办到。如果您查看Eclipse,则有一个函数可以基于XSD生成示例XML。因此,可以对XSD进行自己的XSTL转换,以获得另一个XSLT-但这次基于源XSD。我不会很容易,但是可以实现。