如何将两个xsd模式包含到一个xml文件中?

3
我的问题与两个XSD模式有关,这些模式必须成为XML文档的基础。对我来说,首先创建所需的XML,然后再创建这些XSD模式更容易。因此,我这里有三个文件。
第一个XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema  xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.w3schools.com">

    <xs:element name="studentAI">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="gender">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:enumeration value="female"/>
                            <xs:enumeration value="male"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
                <xs:element name="age">
                    <xs:simpleType>
                        <xs:restriction base="xs:integer">
                            <xs:minInclusive value="0"/>
                            <xs:maxInclusive value="100"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
                <xs:element name="other" type="desc"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="desc">
        <xs:sequence>
            <xs:element name="height" type="xs:string"/>
            <xs:element name="weight" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

</xs:schema>

第二个XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema  xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.w3schools.com">

    <xs:element name="group">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="student" minOccurs="2" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="student">
        <xs:sequence>
             <xs:element name="surname" type="xs:string"/>
           <xs:element name="name" type="xs:string"/>
            <xs:element name="birthday">
                <xs:simpleType>
                    <xs:restriction base="xs:date"/>
                </xs:simpleType>
            </xs:element>
            <xs:element name="parents" type="parentsDetails"/>
            <xs:element name="allCourses" type="allCoursesDetails"/>
        </xs:sequence>
        <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="parentsDetails">
        <xs:sequence>
           <xs:element name="father" type="xs:string"/>
           <xs:element name="mother" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

   <xs:complexType name="allCoursesDetails">
        <xs:sequence>
            <xs:element name="course" type="courseDetails" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
   </xs:complexType>

    <xs:complexType name="courseDetails">
        <xs:attribute name="nr" use="required"/>
    </xs:complexType>

</xs:schema>

我需要根据这两个XSD模式获取的XML文档(抱歉,现在是空的,但当然必须有信息,并且小组中会有不止一个学生):

<group xmlns:xs="http://www.w3schools.com"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://www.w3schools.com ">

    <student id="1">
        <surname></surname>
        <name></name>
        <birthday></birthday>
        <parents>
            <father></father>
            <mother></mother>
        </parents>
        <allCourses>
            <course nr="01"></course>
            <course nr="02"></course>
        </allCourses>
        <studentAI>
            <gender></gender>
            <age></age>
            <other>
                <height></height>
                <weight></weight>
            </other>
        </studentAI>
    </student>
</group>

我真的不知道如何在我的XML文档中包含这两个XSD模式。我应该将它们都包含在XML文档中,还是先将第一个XSD模式包含在第二个模式中(因为在结果XML中是这样做的),然后再将合并后的模式包含在XML文档中?如何做到这一点?
我最大的问题是所有三个文档的上部,其中一个应该放置命名空间的声明等。
至于我正在尝试使用的程序,它是氧气(我有30天的许可证)。
我真的希望有人能帮助我解决这个问题。我也希望我的问题很清楚。
非常感谢您提前的帮助!

XML对于第二个XSD来说是无效的,因为<student>不允许有一个<studentAI>元素(或者我错了吗)?当使用多个XSD时,这些XSD可能有自己的命名空间,并且可以将命名空间绑定到XSD。因此,您可以为XSD 1指定namespaceA,为XSD 2指定namespaceB。 - Wouter J
我会创建一个人实体,赋予它第一个XSD中的特征,并让其他特征扩展它 - 学生是一种人,父母也是人。 - A. Abramov
@Wouter J,感谢您的关注和评论。是的,在student中不允许包含studentAI,但我需要以某种方式组合我的XSD并根据它们创建我的XML。至于命名空间,我认为两个XSD可以有相同的命名空间。因此,我需要将它们包含在我的XML中,但我不知道如何做到这一点... - Ms.Smith
@ A. Abramov,感谢您的关注和评论。如果我理解正确,您的想法很好,但是当将XSD / XSDs包含到XML文档中时,我仍然有疑问... - Ms.Smith
2个回答

2
您可以将两个模式的内容合并到一个唯一的模式中,或者使一个模式包含另一个模式。无论哪种方式,您都应该纠正以下问题:
  1. If you use name or ref to reference a element in a namespace you need to qualify that reference (or simply use your targetNamespace as the default namespace in your xsds that is easier). So, bound your targetNamespace to a prefix.

    xmlns:w3="http://www.w3schools.com"
    

    Then correct your references, for example:

    <xs:element name="allCourses" type="w3:allCoursesDetails"/>
    

    OR simply set the targetNamespace as the default namespace in your xsds:

    xmlns="http://www.w3schools.com"
    

    this way unqualified references point to the default namespace, that is set to the target namespace.

  2. Then you should use elementFormDefault="qualified" in your/yours xs:schema if you want your XML to be valid with all the elements belonging to the targetNampesce. Otherwise some of your XML elements should belong to the target namespace and some of them shouldn't belong to any namespace.

  3. Add the contents of the first schema to the schema containing the student element OR add an include clause that makes the student schema include the studentAI:

    <xs:include schemaLocation="studentAI.xsd"/>
    
  4. After that you only need to validate the XML against the schema containing the student element, so you need to add xsi:schemaLocation in your XML:

    xsi:schemaLocation="http://www.w3schools.com xsd1.xsd"
    
  5. Remember that you can reference elements using ref . You need to add studentAI after allCourses element in the sequence:

    <xs:element name="allCourses" type="allCoursesDetails"/>
    <xs:element ref="studentAI"/>
    
  6. In addition remember that you can simplify the birthday element, you don't need the restriction element if you are not adding any restriction.

希望这能帮到你。 编辑:增加了一些内容(第5和第6项)。

非常感谢您的帮助!我按照您的答案做了一切,它有效!但是并不是全部,因为我仍然无法将XSD1包含到XSD2中。我在我的XSD2中写入了<xs:include schemaLocation="xsd1.xsd"/>,但验证器仍然显示“无法读取模式文档”。我还尝试通过<xs:element ref="xsd1"/>添加引用,但它也没有起作用。也许您可以建议我做错了什么吗?所有其他都很好,再次感谢。 - Ms.Smith
不用客气。可能您忘记了命名空间(如果有的话),或者文件名或路径不正确。由于您正在使用oxygenXML,因此可以打开您的xml文件,然后选择菜单Document>Schema>Associate Schema,然后在下拉菜单中选择您的xsd(如果已经打开)。 - sergioFC
很抱歉,这是用于将您的xsd与xml关联的内容。引用失败是因为模式未正确包含。路径不正确(可能位于不同的文件夹中?)或者xsd无效。 - sergioFC
非常感谢您的帮助!您的答案完全正确,是我把<xs:element ref="studentAI"/>搞混了,因此导致XSD1未被正确地包含在XSd2中。而且,您说得对,我的XSD2也有错误。我进行了更正并再一次仔细地尝试将XSD1包含进去,结果成功了! :) 所以,非常感谢您!如果我的问题占用了您过多的时间,请见谅。 - Ms.Smith

1

首先,你的术语有误。一个模式是一组模式组件。如果你有两个模式,那么实际上你只有一个模式,它是两个模式组件的并集。你所说的不是模式,而是模式文档,这些文件包含模式组件的XML表示。

你的两个模式文档共享相同的目标命名空间。你使用的命名空间 http://www.w3schools.com 是一个糟糕的选择,因为它是一个你不拥有的域名。但这只是一个不良礼仪问题,而不是技术问题。

然而,看到 xsi:schemaLocation="http://www.w3schools.com " 是很奇怪的。如果你必须使用 xsi:schemaLocation 从实例文档引用模式,那么该属性应包含偶数个URI:它基本上是从命名空间URI到具有该目标命名空间的模式文档的URL位置的映射。

如果特定命名空间的模式分布在多个模式文档中,则 xsi:schemaLocation 无法引用它们所有。最好有一个模式文档,完整地描述该命名空间,可以在单个文档中或通过使用 xs:include 声明将所有组成模式文档汇集在一起。

个人而言,我认为从实例文档引用模式文件的想法相当不尽如人意。你只需要验证实例文档,如果你不信任它。但是如果你不信任它,那么你想要验证针对你选择的架构,而不是由实例文档本身选择的架构。说“我想检查这个文档是否有效,但我不关心它是根据哪个模式有效,我会让文档本身来决定。”这并没有多大意义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接