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

kan*_*kan 8 java xml xsd dtd jaxb

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

拥有这些多个根元素会导致一些问题,例如为所有类xjc生成@XmlRootElement,因此我需要添加更多额外的检查.

据我所知,我需要重写生成的XSD,将<xs:element>s 移动到<xs:complexType>s,将element refs 更改为element types等等,但这将是猴子工作太多,无法验证是否所有操作都正确.

有没有更有效的方法来做到这一点?

kan*_*kan 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>
Run Code Online (Sandbox Code Playgroud)

它检测引用的元素定义并使其成为comptexTypes,从而更改引用。所有未引用的元素都成为起始元素。