2013-01-02 21 views
0

我有一個用例來定義XSD架構來描述一個類似於文件和目錄的結構。如何在XML模式中使用recusion和繼承?

  1. File是一個具有多個屬性的複雜類型。
  2. DirectoryFile,所以它應該是File的延伸,或者換句話說,從File繼承。
  3. Directory可以包含更多的Files和子Directories,所以它應該遞歸定義。
  4. File可能是一個元素。
  5. Directory可能是一個根元素。

任何人都可以提供一個示例模式文件嗎?

例如,以下C++代碼編譯/細運行:

#include <iostream> 
    #include <vector> 

    using namespace std; 

    class FileClass { 
    public: 
     string name; 
     int type; 
     string path; 
     long long size; 
     virtual int open(){ 
     }; 
     virtual int close(){ 
     }; 
     virtual ~FileClass(){ 
     }; 
    }; 

    class DirectoryClass: public FileClass { 
    public: 
     vector<FileClass*> dir_contents; 
    }; 

    int main() { 
    cout<<"started"<<endl; 
    DirectoryClass root; 
    root.open(); 
    FileClass* newFile = new FileClass(); 
    root.dir_contents.push_back(newFile); 
    DirectoryClass* subDir = new DirectoryClass(); 
    root.dir_contents.push_back(subDir); 
    root.close(); 
    cout<<"finished"<<endl; 
    } 

正如可以看到的,DirectoryClass僅包含一個FileClass的矢量,它是能夠存儲子顯示目錄因爲DirectoryClass從FileClass衍生的。

+0

爲什麼是目錄中的文件?除了這個想法是你提供你目前的努力,我們的幫助。這不是我們爲15分的重要盼望而爲你做的工作。 –

+0

從文件系統的角度來看,目錄只是另一個文件,其內容是文件名到索引節點的映射,因此它們都具有相似的屬性,如名稱,大小,權限,更改時間等。我在想,在真正的C++/Java/C#代碼中,這樣的概念應該用繼承/遞歸結構輕鬆建模。實際上,我的意圖是在C#/ C++/Java中在XML和這些數據結構之間來回轉換。 – user1943928

+0

地圖不是領土。就物理存儲系統而言,目錄是一個文件,但您沒有指出您的模型包含該功能的理由。如果我爲此選擇了繼承路線(不太可能是誠實的),我會讓它們都繼承自PhysicalFile Class。儘管如此,我更願意在這種情況下使用聚合。 –

回答

1

我同意託尼,爲什麼從文件中獲取目錄? 但是如果那是你的嘗試建模...

Graphical Representation of XSD

<?xml version="1.0" encoding="utf-8" ?> 
<!--Created with Liquid XML Studio 2013 Designer Edition 11.0.0.0 (http://www.liquid-technologies.com)--> 
<xs:schema elementFormDefault="qualified" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:complexType name="FileType"> 
     <xs:attribute name="name" 
         type="xs:string" 
         use="required" /> 
     <xs:attribute name="creationDate" 
         type="xs:dateTime" 
         use="required" /> 
    </xs:complexType> 
    <xs:element name="File" 
       type="FileType" /> 
    <xs:element name="Directory"> 
     <xs:complexType> 
      <xs:complexContent> 
       <xs:extension base="FileType"> 
        <xs:sequence> 
         <xs:element ref="File" 
            minOccurs="0" 
            maxOccurs="unbounded" /> 
         <xs:element ref="Directory" 
            minOccurs="0" 
            maxOccurs="unbounded" /> 
        </xs:sequence> 
       </xs:extension> 
      </xs:complexContent> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

然後,如果你再嘗試讀取/寫入C#,C++,JAVA等你可以看看XML Data Binding結構化XML數據。這將從您的XSD生成一組強類型對象。

+0

感謝所有。真的很感謝你的意見。但是,我在想 – user1943928

+0

從邏輯上說,使用繼承是正確的吧。從語法的角度來看,上面的C++可以正常工作,正如你所看到的,DirectoryClass包含一個向量來存儲它下面的文件和目錄。在Sprotty的XSD文件中,目錄必須包含文件和目錄。 – user1943928

+0

我剛剛在我的原始問題中添加了一個示例C++代碼。請參閱該代碼(不知何故,我不能以正確的格式在這裏發佈)。 – user1943928

0

這改變了一些東西,並且編譯了XML。有兩種方法ComplexType繼承或替代組。複雜類型更適合breif。

enter image description here

<?xml version="1.0" encoding="utf-8" ?> 
<!--Created with Liquid XML Studio 2013 Designer Edition (Trial) 11.0.0.0 (http://www.liquid-technologies.com)--> 
<xs:schema elementFormDefault="qualified" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:complexType name="FileType"> 
     <xs:attribute name="name" 
         type="xs:string" 
         use="required" /> 
     <xs:attribute name="creationDate" 
         type="xs:dateTime" 
         use="required" /> 
     <xs:attribute name="type" 
         type="xs:int" /> 
     <xs:attribute name="size" 
         type="xs:long" /> 
    </xs:complexType> 
    <xs:complexType name="DirectoryType"> 
     <xs:complexContent> 
      <xs:extension base="FileType"> 
       <xs:sequence> 
        <xs:element name="Content" 
           type="FileType" 
           minOccurs="0" 
           maxOccurs="unbounded" /> 
       </xs:sequence> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 
    <xs:element name="Directory" 
       type="DirectoryType" /> 
</xs:schema> 

示例XML

<?xml version="1.0" encoding="utf-8"?> 
<!-- Created with Liquid XML Studio 2013 Designer Edition (Trial) 11.0.0.0 (http://www.liquid-technologies.com) --> 
<Directory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:noNamespaceSchemaLocation="FoldersCT.xsd" 
      name="string" 
      creationDate="1975-12-12T08:25:00.94" 
      type="393" 
      size="-5191"> 
    <Content name="FileA1" 
      creationDate="1993-02-23T21:13:52.11" 
      type="4931" 
      size="-1984" /> 
    <Content name="FileA2" 
      creationDate="1991-12-26T15:57:44.30" 
      type="-6155" 
      size="18" /> 
    <Content name="FileA3" 
      creationDate="1979-01-05T21:36:13.80" 
      type="8362" 
      size="5579" /> 
    <Content xsi:type="DirectoryType" 
      name="DirA4" 
      creationDate="1979-01-05T21:36:13.80" 
      type="8362" 
      size="5579"> 
     <Content name="FileB1" 
       creationDate="1979-01-05T21:36:13.80" 
       type="8362" 
       size="5579" /> 
     <Content name="FileB2" 
       creationDate="1979-01-05T21:36:13.80" 
       type="8362" 
       size="5579" /> 
    </Content> 
</Directory> 

注意使用XSI的:在目錄類型= 「DirectoryType」 屬性。這告訴XML解析器該內容是由DirectoryType定義的。沒有這個文件。這是你的規格說的,但它會非常凌亂。

另一種解決方案是使用替換組,我個人不喜歡替換組,因爲它們在模式中難以閱讀。這種效果與原始解決方案相同。

enter image description here

<?xml version="1.0" encoding="utf-8" ?> 
<!--Created with Liquid XML Studio 2013 Designer Edition (Trial) 11.0.0.0 (http://www.liquid-technologies.com)--> 
<xs:schema elementFormDefault="qualified" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:complexType name="FileType"> 
     <xs:attribute name="name" 
         type="xs:string" 
         use="required" /> 
     <xs:attribute name="creationDate" 
         type="xs:dateTime" 
         use="required" /> 
     <xs:attribute name="type" 
         type="xs:int" /> 
     <xs:attribute name="size" 
         type="xs:long" /> 
    </xs:complexType> 
    <xs:element name="File" 
       type="FileType" 
       substitutionGroup="File" /> 
    <xs:element name="Directory" 
       substitutionGroup="File"> 
     <xs:complexType> 
      <xs:complexContent> 
       <xs:extension base="FileType"> 
        <xs:sequence> 
         <xs:element ref="File" 
            minOccurs="0" 
            maxOccurs="unbounded" /> 
        </xs:sequence> 
       </xs:extension> 
      </xs:complexContent> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

示例XML

<?xml version="1.0" encoding="utf-8"?> 
<!-- Created with Liquid XML Studio 2013 Designer Edition (Trial) 11.0.0.0 (http://www.liquid-technologies.com) --> 
<Directory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:noNamespaceSchemaLocation="FoldersSG.xsd" 
      name="string" 
      creationDate="1992-01-13T17:58:08.38" 
      type="-2296" 
      size="-8752"> 
    <File name="string" 
      creationDate="1982-11-03T17:57:40.96" 
      type="6813" 
      size="5278" /> 
    <File name="string" 
      creationDate="1986-12-08T12:38:03.46" 
      type="4479" 
      size="8453" /> 
    <Directory name="string" 
       creationDate="1992-01-13T17:58:08.38" 
       type="-2296" 
       size="8752"> 
     <File name="string" 
       creationDate="1982-11-03T17:57:40.96" 
       type="6813" 
       size="5278" /> 
     <File name="string" 
       creationDate="1986-12-08T12:38:03.46" 
       type="4479" 
       size="8453" /> 
    </Directory> 
</Directory>