2012-05-24 60 views
8

我有幾個大的DTD文件。我用trang將它們轉換成XSD文件,所以我可以很容易地從JAXB和其他工具中使用它。但是,生成的XSD文件在頂層具有所有聲明的元素。這意味着任何元素都可以是輸入XML的根元素。我只想指定一個特定的元素。使用已定義的根(開始)元素將DTD轉換爲XSD

有了這些多個根元素會導致一些問題,例如xjc爲所有類生成@XmlRootElement,所以我需要添加更多附加檢查。

據我瞭解,我需要重寫生成的XSD,移動<xs:element> s到<xs:complexType> S,改變element ref s轉換element type S和等等,但是這將是太多了猴子的工作,沒有辦法驗證是否全部完成正確。

有沒有更有效的方法來做到這一點?

+0

+1的問題是有道理的,但我們也明確指出DTD到XSD轉換始終只是近似。 –

+0

@JirkaHanika據我所知,生成的XSD很接近DTD。除了可能的DOCTYPE定義(雖然沒有意外)和一些命名空間的東西。另外一些奇怪的DTD構造不能整齊地轉換成XSD。我目前面臨的唯一問題是,DTD沒有定義根元素的概念。 (RelaxNG確實用''來定義它,但是它不被支持,'xjc'因此失敗)。 – kan

+0

是的,但命名空間的東西是一個biggie。另外很多被命名爲相似的構造意味着完全不同的東西。對第一個答案+1,因爲它不假裝任何XSD語義。 –

回答

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,改變裁判。所有未引用的元素都將成爲啓動元素。

0

從你所描述的,而忽略了一些評論中指出的轉換的「保真度」,我只處理這樣的事實,你只是在尋找一些自動的方式(我呼叫)XML架構重構。我與QTAssistant相關聯,這是一種適合這種工作的產品,所以這就是我該怎麼做的......

無論如何,你必須手工做的一件事就是弄清楚並捕獲你希望看到的元素列表(或不是)......你完成了:點擊一個按鈕或調用一個命令行,你就會知道是否生成了有效的XSD。

一個重構引擎採用訪問者模式,在你的情況下,本質上是做你所需要的:創建需要的地方全局類型,刪除不需要的全局元素定義,並替換所有與再送出在線聲明元素。 (對於閱讀這個知道替換組的人來說,這個重構不會替代對替換組頭部的引用;因爲我們正在討論來自DTD的XSD,所以這不是問題)。

這種簡單,並且是可重複的和可靠的事實,將是使用專門的重構工具的主要優點;另一個優點:它也可以重新分配xml命名空間,無論如何你想...

如果你有興趣瞭解更多的細節,請告訴我,我會用一個小樣本和一些插圖更新這篇文章。