0

考虑以下 XML 文档:

<?xml version="1.0" encoding="utf-8"?>
<fooDb version="1.0.0.0" xmlns="http://tempurl.org/2013/01/Example">
  <provider>Some Provider</provider>
  <connectionSettings xmlns="http://tempurl.org/2013/01/Example.SomeProvider">
    <protocol>https</protocol>
    <server>contoso-server</server>
    <port>8080</port>
    <project>Tailspin Toys</project>
  </connectionSettings>
</fooDb>

基本上,我有这个<connectionSettings>元素,我希望客户能够自定义它。我不希望整个“示例”项目知道特定提供商对其连接设置做了什么。我对此模式的第一次尝试如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ExampleConfiguration"
    xmlns="http://tempurl.org/2013/01/Example"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://tempurl.org/2013/01/Example"
    elementFormDefault="qualified">

  <!-- Root element for configurations. -->
  <xs:element name="fooDb">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="provider" minOccurs="1" maxOccurs="1" />
        <xs:element ref="connectionSettings" minOccurs="1" maxOccurs="1" />
      </xs:sequence>
      <xs:attribute name="version" type="version" />
    </xs:complexType>
  </xs:element>

  <xs:element name="provider" type="xs:string" />

  <!-- Individual providers provide their own connection settings. -->
  <xs:element name="connectionSettings">
    <xs:complexType>
      <xs:sequence>
        <xs:any processContents="strict" minOccurs="0" maxOccurs="unbounded"
                namespace="##other" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- Requires that an element be empty. -->
  <xs:simpleType name="empty">
    <xs:restriction base="xs:string">
      <xs:enumeration value=""/>
    </xs:restriction>
  </xs:simpleType>

  <!-- Current version is 1.0.0.0. -->
  <xs:simpleType name="version">
    <xs:restriction base="xs:string">
      <xs:enumeration value="1.0.0.0"/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>

一个特定的提供者,我们称之为“SomeProvider”,定义了它自己的连接设置:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="SomeProviderConfiguration"
    xmlns="http://tempurl.org/2013/01/Example.SomeProvider"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://tempurl.org/2013/01/Example.SomeProvider"
    elementFormDefault="qualified">

  <xs:element name="connectionSettings">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="protocol" type="protocol" />
        <xs:element name="server" type="xs:string" />
        <xs:element name="port" type="port" />
        <xs:element name="project" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:simpleType name="protocol">
    <xs:restriction base="xs:string">
      <xs:enumeration value="http" />
      <xs:enumeration value="https" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="port">
    <xs:restriction base="xs:int">
      <xs:minInclusive value="0" />
      <xs:maxInclusive value="65535" />
    </xs:restriction>
  </xs:simpleType>

</xs:schema>

当我尝试验证这一点时,我遇到了失败,因为外部架构期望<connectionSettings>节点被定义为“Example”命名空间的一部分,但它确实属于“Example.SomeProvider”命名空间(至少正如我在上面定义的那样)。

这样的事情是否可以以这种方式在模式中表达,还是我必须求助于模式包含方案?

4

1 回答 1

1

如果我使用您提供的示例 XML,则不得在“示例”命名空间中定义“连接设置”。你的 fooDb 看起来像

<xs:element name="fooDb">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="provider" minOccurs="1" maxOccurs="1" />
        <xs:any processContents="strict" minOccurs="1" maxOccurs="1"
                namespace="##other" />
      </xs:sequence>
    </xs:complexType>
</xs:element>

但我猜你试图强制提供者覆盖“connectionSettings”而不共享与“示例”相同的命名空间。我不认为这是可能的。

如果你真的想确保“connectionSettings”是“Example”命名空间的一部分,那么提供者需要像下面这样调整他们的 XSD

    <?xml version="1.0" encoding="utf-8"?>
<xs:schema id="SomeProviderConfiguration"
    xmlns="http://tempurl.org/2013/01/Example.SomeProvider"
    xmlns:par="http://tempurl.org/2013/01/Example"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://tempurl.org/2013/01/Example.SomeProvider"
    elementFormDefault="qualified">

        <xs:element name="protocol" type="protocol" />
        <xs:element name="server" type="xs:string" />
        <xs:element name="port" type="port" />
        <xs:element name="project" type="xs:string" />

  <xs:simpleType name="protocol">
    <xs:restriction base="xs:string">
      <xs:enumeration value="http" />
      <xs:enumeration value="https" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="port">
    <xs:restriction base="xs:int">
      <xs:minInclusive value="0" />
      <xs:maxInclusive value="65535" />
    </xs:restriction>
  </xs:simpleType>

</xs:schema>

或者 XML 实例必须如下所示

<?xml version="1.0" encoding="UTF-8"?>
<p:fooDb xmlns:p="http://tempurl.org/2013/01/Example" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="..."
    xmlns:inc="http://tempurl.org/2013/01/Example.SomeProvider">
  <p:provider>p:provider</p:provider>
    <p:connectionSettings>
      <protocol xsi:type="inc:protocol" xmlns="http://tempurl.org/2013/01/Example.SomeProvider">https</protocol>
      <server xmlns="http://tempurl.org/2013/01/Example.SomeProvider">localhost</server>
      <port xsi:type="inc:port" xmlns="http://tempurl.org/2013/01/Example.SomeProvider">8001</port>
      <project xmlns="http://tempurl.org/2013/01/Example.SomeProvider">example</project>
    </p:connectionSettings>
</p:fooDb>
于 2013-01-23T17:45:15.500 回答