使用定义的根(起始)元素将DTD转换为XSD

时间:2012-05-24 10:16:51

标签: java xml xsd jaxb dtd

我有几个大型DTD文件。我已经使用trang将它们转换为XSD文件,因此我可以轻松地从JAXB和其他实用程序中使用它。但是,生成的XSD文件在顶层具有所有声明的元素。这意味着任何元素都可以是输入XML的根元素。我只想指定一个特定的元素。

具有这些多个根元素会导致一些问题,例如: xjc为所有类生成@XmlRootElement,因此我需要添加更多其他检查。

据我了解,我需要重写生成的XSD,将<xs:element>移至<xs:complexType> s,将element ref更改为element type s,依此类推将猴子工作太多,无法验证是否所有工作都正确。

有更有效的方法吗?

2 个答案:

答案 0 :(得分:0)

根据你所描述的内容,并忽略了一些评论中指出的转换的“保真度”,我只是在处理你只是在寻找一些自动方式(我称之为) XML架构重构 。我与QTAssistant相关联,这是一种专门用于此类工作的产品,所以这就是我要做的...

你要做的一件事,无论如何,都要找出并捕捉你想要看作根(或不是)的元素列表......然后你就完成了:按一个按钮,或者调用命令行,您将确定是否生成了有效的XSD。

重构引擎使用访问者模式,在您的情况下基本上执行您需要的操作:在需要时创建全局类型,删除不需要的全局元素定义,并使用内联声明替换任何refed元素。

(对于那些知道替换组的人来说,这种重构不会替换对替换组的头部的引用;因为我们从DTD谈论XSD,这不是问题所在。)

这种简单性以及可重复和可靠的事实将是使用专门的重构工具的主要优势;另一个优点:它还可以重新分配xml命名空间,无论如何你想...

如果您对更多细节感兴趣,请与我们联系,我会用一些小样本和一些插图来更新这篇文章。

答案 1 :(得分:0)

我使用简单的XSLT转换来处理生成的XSD。适合我的情况:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
        >
    <xsl:template match="@*|node()|comment()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()|comment()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="xs:element/@ref"/>
    <xsl:template match="xs:element[@ref]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="type"><xsl:value-of select="@ref"/></xsl:attribute>
            <xsl:attribute name="name"><xsl:value-of select="@ref"/></xsl:attribute>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="xs:element[@name = //xs:element/@ref and xs:complexType]">
        <xs:complexType name="{@name}">
            <xsl:apply-templates select="xs:complexType/node()"/>
        </xs:complexType>
    </xsl:template>
    <xsl:template match="xs:element[@name = //xs:element/@ref and @type]">
        <xsl:choose>
            <xsl:when test="//xs:complexType[@name = current()/@type]">
                <xs:complexType name="{@name}">
                    <xs:complexContent>
                        <xs:extension base="{@type}"/>
                    </xs:complexContent>
                </xs:complexType>
            </xsl:when>
            <xsl:otherwise>
                <xs:simpleType name="{@name}">
                    <xs:restriction base="{@type}"/>
                </xs:simpleType>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

它检测引用的元素定义并使它们comptexType s,更改引用。所有未引用的元素都成为开始元素。