【问题标题】:What does targetNamespace do ? Am I getting it right?targetNamespace 是做什么的?我说对了吗?
【发布时间】:2013-05-10 12:06:45
【问题描述】:

这是我的 XSD 的 <schema> 标签:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.cmu.edu/ns/blank"
    targetNamespace="http://www.cmu.edu/ns/blank"
    elementFormDefault="qualified">  

如果我的理解是正确的,这就是它的意思:

  • 此架构本身属于http://www.w3.org/2001/XMLSchema 命名空间
  • XML 实例的根应该属于http://www.cmu.edu/ns/blank 命名空间
  • XML 实例中所有没有前缀的元素都自动属于http://www.cmu.edu/ns/blank 命名空间,因为elementFormDefault合格
  • 问题1:我的理解是否正确。如果没有,有什么问题?

    问题 2 看看下面提到的 XML 实例:

    <people
    xmlns="http://www.cmu.edu/ns/blank"
    xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.cmu.edu/ns/blank student.xsd"
    >
        <student>
            <name>John</name>
            <course>Computer Technology</course>
            <semester>6</semester>
            <scheme>E</scheme>
        </student>
    </people>  
    

    这里的一切都属于http://www.cmu.edu/ns/blank命名空间,包括&lt;student&gt;和由于elementFormDefault而包含在其中的元素。 正确吗?

    问题3
    现在,我想添加来自各个大学的&lt;student&gt;。带有前缀,例如伯克利的berk,哈佛的harv,等等。每个&lt;student&gt; 都有一组不同的元素。我想验证这一点。 这怎么可能?

    【问题讨论】:

    • Q3 听起来不太适合用于 XML 命名空间。这就像在编程语言类型系统中定义一个BerkStudent 类和一个HarvStudent 类。
    • @McDowell 是的,你是对的,但是我可以在伯克利和哈佛的 XSD 中使用 &lt;xs:extention&gt; 并添加更多字段。这就像泛化/专业化关系:)
    • 您在向后考虑 - 架构不会“自动导致”实例文档中的任何内容,由您在实例文档中使用默认命名空间和前缀声明的正确组合使其与架构所期望的相匹配。 elementFormDefault 是影响这些预期的因素之一。
    • @IanRoberts 由于模式实例的根属于某个命名空间,所有子元素也将属于该命名空间(即继承),除非另有说明?
    • @LittleChild 这是正常的 XML 规则,无论是否涉及架构。对于&lt;people xmlns="example"&gt;&lt;student/&gt;&lt;/people&gt;,student 元素位于example 命名空间中,但对于&lt;p:people xmlns:p="example"&gt;&lt;student/&gt;&lt;/p:people&gt;,它不在。

    标签: xml validation xsd


    【解决方案1】:

    (1)前两点OK;第三个:

    All the elements within the XML instance which do not have a prefix automatically belong to http://www.cmu.edu/ns/blank namespace as elementFormDefault is qualified

    不正确。

    在架构中声明前缀并不意味着 XML 实例必须使用相同的前缀。 XSD 文件中的任何命名空间声明,仅适用于 XSD 的 XML 文件(XSD 是 XML,因此...)

    一般来说,没有办法假设任何带前缀或不带前缀的元素名称;即下面的例子都是正确的。

    <some xmlns="" .../>
    <some xmlns="urn:tempuri-org:XSD:1" .../>
    <x:some xmlns:x="urn:tempuri-org:XSD:1" .../>
    

    唯一可以确定的是,表示非限定名称的唯一方法是使用不带前缀的名称(即不能为“空”命名空间添加前缀)。

    elementFormDefault 控制元素名称的形式,当元素在内容模型中声明时(即不是全局的)。

    (2) 部分正确。 because of elementFormDefault. 部分不正确。同样,XSD 只是一种模式规范。 XML 存在并且有自己的规则,与 XSD 或任何其他模式语言无关。此处适用的规则是XML namespaces,特别是scoping

    (3) 您必须为每个命名空间创建一个 XSD;在每个命名空间中,您声明学生及其内容。然后定义人员的 XSD 将导入其他 XSD 并适当地引用学生。

    所以这是一个基本设置:

    伯克利.xsd

    <?xml version="1.0" encoding="utf-8" ?>
    <!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
    <xsd:schema targetNamespace="urn:berkeley-org" xmlns="urn:berkeley-org" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <xsd:element name="student"/>   
    </xsd:schema>
    

    哈佛.xsd

    <?xml version="1.0" encoding="utf-8" ?>
    <!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
    <xsd:schema targetNamespace="urn:harvard-org" xmlns="urn:harvard-org" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <xsd:element name="student"/>   
    </xsd:schema>
    

    people.xsd

    <?xml version="1.0" encoding="utf-8" ?>
    <!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
    <xsd:schema targetNamespace="urn:people-org" xmlns="urn:people-org" xmlns:harv="urn:harvard-org" xmlns:berk="urn:berkeley-org" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <xsd:import namespace="urn:harvard-org"  schemaLocation="harvard.xsd"/>
        <xsd:import namespace="urn:berkeley-org" schemaLocation="berkeley.xsd"/>
    
        <xsd:element name="people">
            <xsd:complexType>
                <xsd:choice maxOccurs="unbounded">
                    <xsd:element ref="harv:student"/>
                    <xsd:element ref="berk:student"/>               
                </xsd:choice>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>
    

    文件图:

    一个示例 XML(显示名称空间的使用):

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
    <people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:harv="urn:harvard-org" xmlns:berk="urn:berkeley-org" xmlns="urn:people-org">
        <harv:student/>
        <berk:student/>
    </people>
    

    【讨论】:

    • 我在这里阅读了更多关于elementFormDefault 的内容:levijackson.net/elementformqualified-what-is-it,这为我解决了这个神话。总结一下:elementFormDefault="qualified"——所有元素都属于targetNameSpace。如果 unqualified 它们不属于任何地方,除非声明了“空白”命名空间。推论来自网站
    • @LittleChild 没有“除非” - xmlns 声明不会进入其中。在 complexType 中声明的 elementFormDefault="qualified" 局部元素进入架构的 targetNamespace,不合格的它们不在命名空间中(即只有全局顶级元素声明采用目标命名空间)。
    • @LittleChild / @IanRoberts:严格来说,这里要记住的关键是“默认”,即 elementForm Default 在不使用form 属性时提供默认(初始化器)。换句话说,无论默认值是什么,form 属性都是优先的。所以,即使在这里,也有一个unless:即With elementFormDefault="qualified" local elements declared inside a complexType go into the targetNamespace of the schema,,除非表单属性另有说明。
    【解决方案2】:

    Petru's answer 是一个不错的选择,但它要求基础“人”模式了解(并导入)所有不同的大学特定模式 - 如果你想添加一所新大学,你必须更新基础要匹配的架构。另一种方法是通过让基本模式声明一个基本“学生”类型来反转导入的方向,可能包含所有大学共有的元素,其他模式使用substitution group 机制进行扩展。

    people.xsd

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="urn:people"
        xmlns:p="urn:people"
        elementFormDefault="unqualified">
    
      <xs:element name="people">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="p:student" minOccurs="0" maxOccurs="unbounded" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    
      <xs:complexType name="studentType">
        <xs:sequence>
          <xs:element name="name" type="xs:string" />
        </xs:sequence>
      </xs:complexType>
    
      <xs:element name="student" type="p:studentType" />
    </xs:schema>
    

    harvard.xsd

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="urn:harvard"
        xmlns:p="urn:people"
        elementFormDefault="unqualified">
      <xs:import namespace="urn:people"  schemaLocation="people.xsd"/>
    
      <xs:element name="student" substitutionGroup="p:student">
        <xs:complexType>
          <xs:extension base="p:studentType">
            <xs:element name="harvardId" type="xs:string" />
          </xs:extension>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    berkeley.xsd

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="urn:berkeley"
        xmlns:p="urn:people"
        elementFormDefault="unqualified">
      <xs:import namespace="urn:people"  schemaLocation="people.xsd"/>
    
      <xs:element name="student" substitutionGroup="p:student">
        <xs:complexType>
          <xs:extension base="p:studentType">
            <xs:element name="berkeleyId" type="xs:string" />
          </xs:extension>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    实例文档

    <p:people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:harv="urn:harvard" xmlns:berk="urn:berkeley" xmlns:p="urn:people"
              xsi:schemaLocation="urn:people people.xsd urn:harvard harvard.xsd
                                  urn:berkeley berkely.xsd>
      <harv:student>
        <name>John</name>
        <harvardId>12345</harvardId>
      </harv:student>
      <berk:student>
        <name>Mary</name>
        <berkeleyId>ABCDE</berkeleyId>
      </berk:student>
    </p:people>
    

    请注意,我在此示例中使用了elementFormDefault="unqualified" 来简化实例文档中的命名空间。如果我使用了qualified,那么你必须说类似

    <harv:student>
      <p:name>John</p:name>
      <harv:harvardId>12345</harv:harvardId>
    </harv:student>
    

    (即,harv:student 下从基本 p:studentType 继承的元素必须在 urn:people 命名空间中,但在 harvard.xsd 扩展中声明的元素必须在 urn:harvard 命名空间中) .

    这里要理解的重点是:

    • people 模式声明了一个 global 复杂类型 studentType 和一个此类型的 global 元素 student,并将 people 元素声明为{urn:people}student 的序列。
    • 每个学院特定的模式都使用substitutionGroup="p:student" 和扩展p:studentType 的类型声明自己的元素。这告诉验证器,在任何需要 {urn:people}student 的地方,{urn:college}student 也是可以接受的。
    • 当您想添加一所新学院时,您只需在同一 substitutionGroup 中创建一个包含新元素的类似架构,您可以在实例文档中引用它 - 无需更改 people 架构。

    【讨论】:

    • 也不错;我没有在这里提到但我把它放在许多其他答案中的原因,例如here 是替代组对于初学者来说是一个更高级的概念,而且它在各种实现中没有得到广泛和/或同等支持。因此,如果我可以建议,既然您已经开始了它:如果替换组的头部被标记为抽象,则实现最大互操作;您不需要为学生定义基本类型...
    • (cont'd) ... 除非你想要一个通用的抽象;最佳实践是将可重用组件(学生及其类型)的定义与它的使用(这里是人)分开。所以最终的设置(我称之为生产级别)是让人员模式引用学生模式,然后由其他两个模式引用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 2011-10-10
    相关资源
    最近更新 更多