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 を使用する場合、"Example" 名前空間で "connectionSettings" を定義してはなりません。あなたの 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>

しかし、「Example」と同じ名前空間を共有せずに「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 に答える