8

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

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

据我了解,我需要重写生成的 XSD,将<xs:element>s 移动到<xs:complexType>s,将element refs 更改为element types 等等,但这将是太多的猴子工作,无法验证是否全部正确完成。

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

4

2 回答 2

0

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

无论如何,您必须手动完成的一件事是找出并捕获您希望以 root 身份(或不以 root 身份查看)的元素列表......您就完成了:点击一个按钮,或调用一个命令行,您将确定是否生成了有效的 XSD。

重构引擎采用访问者模式,在您的情况下,它基本上可以满足您的需求:在需要时创建全局类型,删除不需要的全局元素定义,并用内联声明替换任何引用的元素。

(对于阅读本文并了解替换组的任何人,此重构并不是替换对替换组负责人的引用;因为我们讨论的是来自 DTD 的 XSD,所以这不是问题)。

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

如果你对更多细节感兴趣,请告诉我,我会用一个小样本和一些插图来更新这篇文章。

于 2012-05-25T18:23:32.153 回答
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>

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

于 2012-05-28T09:20:10.513 回答