targetNamespace做什么?我做对了吗?

时间:2013-05-10 12:06:46

标签: xml validation xsd

以下是我的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 namespace
  • XML实例中没有前缀的所有元素都自动属于http://www.cmu.edu/ns/blank命名空间,因为elementFormDefault 限定
  • 问题1 :我的理解是否正确。如果没有,有什么不对?

    Question2 查看下面提到的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名称空间,包括<student>以及因elementFormDefault而包含的内容。 正确吗?

    问题3
    现在,我想添加各大学的<student>。 Berkley的前缀为berk,哈佛的前缀为harv等。每个<student>都有一组不同的元素。我想验证这一点。 这怎么可能?

    2 个答案:

    答案 0 :(得分:4)

    (1)前两点都可以;第三个:

    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并适当地引用学生。

    所以这是一个基本设置:

    Berkeley.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>
    

    Harvard.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>
    

    文件图表:

    enter image description here

    示例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>
    

    enter image description here

    答案 1 :(得分:1)

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

    <强> 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架构声明此类型的全局复杂类型studentType全局元素student,并声明people元素作为{urn:people}student的序列。
    • 每个特定于大学的架构都使用substitutionGroup="p:student"声明自己的元素,并使用扩展p:studentType的类型。这告诉验证者,在预期{urn:people}student的任何地方,{urn:college}student也是可以接受的。
    • 当你想要添加一个新的大学时,你只需在同一个substitutionGroup中创建一个具有新元素的类似模式,你可以在实例文档中引用它 - 不需要更改{{1} } schema。