如何在XML Schema中使用recusion和inheritance?

时间:2013-01-02 23:21:36

标签: xsd

我有一个用例来定义XSD架构来描述类似于文件和目录的结构。

  1. File是一个具有多个属性的复杂类型。
  2. DirectoryFile,因此它应该是File的扩展名,换言之,继承自File
  3. Directory可以包含更多Files和子Directories,因此应该以递归方式定义。
  4. File可能是一个元素。
  5. Directory可以是根元素。
  6. 任何人都可以提供示例模式文件吗?

    例如,以下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派生的。

2 个答案:

答案 0 :(得分:1)

我同意Tony,为什么从File获取目录? 但如果这就是你想要建模的东西......

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数据,您可以查看XML Data Binding。这会从您的XSD生成一组强类型对象。

答案 1 :(得分: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:type =“DirectoryType”属性。这告诉XML Parser内容是由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>