【问题标题】:How to include 2 xsd schemas into 1 xml file?如何将 2 个 xsd 模式包含到 1 个 xml 文件中?
【发布时间】:2015-08-15 17:53:21
【问题描述】:

我的问题是关于 2 个 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>

以及我需要基于这 2 个 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 文档中包含这 2 个 XSD 模式。我应该将它们都包含到 XML 文档中,还是应该首先将第一个 XSD 模式包含到第二个中(就像结果 XML 一样),然后将统一的模式包含到 XML 文档中?以及如何做到这一点?

我最大的问题是关于所有三个文档的上半部分,应该在哪里放置命名空间的声明等等。

至于我尝试使用的程序是 Oxygen(我有 30 天的 lisense)。

我真的希望有人能帮助我解决这个问题。我也希望我的问题很清楚。

非常感谢您的帮助!

【问题讨论】:

  • XML 对于第二个 XSD 无效,因为 &lt;student&gt; 不允许有 &lt;studentAI&gt; 元素(或者我错了)?使用多个 XSD 时,这些 XSD 可能有自己的命名空间,您可以将命名空间绑定到 XSD。所以你有 XSD 1 的 namespaceA 和 XSD 2 的 namespaceB。
  • 我会创建一个人实体,赋予它第一个 XSD 中的特征,并让其他特征扩展它 - 学生是人,父母也是人。
  • @Wouter J,感谢您的关注和评论。是的,student 不允许在里面有studentAI,但我需要以某种方式组合我的 XSD 并在它们的基础上创建我的 XML。至于命名空间,我认为两个 XSD 可以具有相同的命名空间。所以我需要将它们包含到我的 XML 中 - 我不知道该怎么做......
  • @A. Abramov,感谢您的关注和评论。你的想法很好——如果我理解正确的话——但在将 XSD/XSD 包含到 XML 文档中时我仍然有疑问......

标签: xml xsd


【解决方案1】:

您可以将两个架构的内容合并到一个唯一架构中,以使一个架构包含另一个架构。无论如何,您应该纠正这个问题:

  1. 如果您使用nameref 来引用命名空间中的元素,则需要限定该引用(或者简单地将您的targetNamespace 用作xsds 中的默认命名空间,这样更容易)。因此,将您的 targetNamespace 绑定到前缀

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

    然后更正您的参考文献,例如:

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

    或者只需将 targetNamespace 设置为 xsds 中的默认命名空间

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

    这种方式非限定引用指向默认命名空间,即设置为目标命名空间。

  2. 如果您希望您的 XML 对属于 targetNampesce 的所有元素都有效,那么您应该在您/您的 xs:schema使用 elementFormDefault="qualified"。否则,您的一些 XML 元素应该属于目标命名空间,而其中一些不应该属于任何命名空间。

  3. 将第一个模式的内容添加到包含 student 元素的模式或 添加一个包含子句,使 student 模式包含学生AI

    <xs:include schemaLocation="studentAI.xsd"/>
    
  4. 之后,您只需针对包含 student 元素的架构验证 XML,因此您需要在 XML 中添加 xsi:schemaLocation

    xsi:schemaLocation="http://www.w3schools.com xsd1.xsd"
    
  5. 请记住,您可以使用 ref 引用元素。您需要在序列中的 allCourses 元素之后添加 studentAI

    <xs:element name="allCourses" type="allCoursesDetails"/>
    <xs:element ref="studentAI"/>
    
  6. 另外请记住,您可以简化生日元素,如果不添加任何限制,则不需要限制元素。

希望对你有所帮助。

编辑:添加了更多内容(第 5 项和第 6 项)。

【讨论】:

  • 非常感谢您的帮助!我按照你的回答做了一切,它有效!但并非一切,因为我仍然无法将 XSD1 包含到 XSD2 中。我确实在我的 XSD2 中写了&lt;xs:include schemaLocation="xsd1.xsd"/&gt;,但验证器仍然显示“无法读取架构文档”。我也尝试通过这个&lt;xs:element ref="xsd1"/&gt; 添加一个引用,但它也没有工作。也许你可以建议我做错了什么?其他一切正常,再次感谢您。
  • 不客气。可能您忘记了命名空间(如果有)或者文件名或路径不正确。当您使用oxyXML时,您可以打开您的xml文件,然后选择菜单文档>架构>关联架构,然后在下拉列表中选择您的xsd(如果它已打开)
  • 对不起,这是为了将您的 xsd 关联到您的 xml。 Ref 失败,因为未正确包含架构。路径不正确(可能位于不同的文件夹中?)或 xsd 无效。
  • 再次感谢您的帮助!您的回答完全正确,这是我与&lt;xs:element ref="studentAI"/&gt; 混淆了一些东西,这就是为什么 XSD1 没有正确包含在 XSd2 中的原因。而且,你是对的,我的 XSD2 有一个错误。我更正了它并尝试再次更专注地包含 XSD1,它成功了! :) 所以,非常感谢!很抱歉,如果您的回答占用了您太多时间。
【解决方案2】:

首先,您的术语是飘忽不定的。架构是一组架构组件。如果你有两个模式,那意味着你真的有一个模式,它是两个模式组件的联合。您所说的不是架构,而是架构文档,即包含架构组件的 XML 表示的文件。

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

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

如果特定命名空间的架构被拆分为多个架构文档,则 xsi:schemaLocation 不能全部引用它们。最好有一个模式文档来完整地描述命名空间,或者在单个文档中,或者通过使用 xs:include 声明将所有组成模式文档组合在一起。

就个人而言,我发现从实例中引用模式文档的想法并不令人满意。如果您不信任实例文档,则只需验证它。但是,如果您不信任它,那么您希望针对您选择的模式进行验证,而不是实例文档本身选择的模式。说“我想检查这个文档是否有效,但我不在乎它对什么架构有效,我会让文档自己来决定。”没有多大意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-09
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-24
    相关资源
    最近更新 更多