3

受信した XML ドキュメントの XSD スキーマを作成しようとしてstaffいますが、同じ名前の要素が 2 つあります。

同じ名前の要素が 2 つある場合でも、この XML のスキーマを作成する方法はありますか?

XML:

<contacts>
    <staff count="248" pagesize="284">
    <staff id="1231">
    <Forename>test</Forename>
    <Surname>test</Surname>
    <DateOfBirth>0000-00-00</DateOfBirth>
    <Gender/>
    <Address1/>
    <Address2/>
    <Town/>
    <County/>
    <Telephone/>
    <Mobile/>
    <Email/>
    <Created>0000-06-18 09:46:32</Created>
    <CreatedBy>test</CreatedBy>
    <Updated>2000-06-18 09:46:32</Updated>
    <UpdatedBy>test</UpdatedBy>
    <Archived>0000-00-00 00:00:00</Archived>
    <ArchivedBy/>
    <Postcode/>
    <Age>0</Age>
    <RestrictedRecord>0</RestrictedRecord>
    <Disability_S_24/>
    <Ethnicity_S_25/>
    <Type>8</Type>
    <PersonID>1231</PersonID>
    <TypeName>staff</TypeName>
    </staff>
</staff>
</contacts>

これまでのスキーマ:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="contacts">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="staff"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="staff">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" ref="staff"/>
            </xs:sequence>
            <xs:attribute name="count" use="required" type="xs:integer"/>
            <xs:attribute name="pagesize" use="required" type="xs:integer"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="staff">
        <xs:complexType>
            <xs:all  >
                <xs:element ref="Forename" minOccurs="0"/>
                <xs:element ref="Surname" minOccurs="0"/>
                <xs:element ref="DateOfBirth" minOccurs="0"/>
                <xs:element ref="Gender" minOccurs="0"/>
                <xs:element ref="Address1" minOccurs="0"/>
                <xs:element ref="Address2" minOccurs="0"/>
                <xs:element ref="Town" minOccurs="0"/>
                <xs:element ref="County" minOccurs="0"/>
                <xs:element ref="Telephone" minOccurs="0"/>
                <xs:element ref="Mobile" minOccurs="0"/>
                <xs:element ref="Email" minOccurs="0"/>
                <xs:element ref="Created" minOccurs="0"/>
                <xs:element ref="CreatedBy" minOccurs="0"/>
                <xs:element ref="Updated" minOccurs="0"/>
                <xs:element ref="UpdatedBy" minOccurs="0"/>
                <xs:element ref="Archived" minOccurs="0"/>
                <xs:element ref="ArchivedBy" minOccurs="0"/>
                <xs:element ref="Postcode" minOccurs="0"/>
                <xs:element ref="Age" minOccurs="0"/>
                <xs:element ref="RestrictedRecord" minOccurs="0"/>
                <xs:element ref="Disability_S_24" minOccurs="0"/>
                <xs:element ref="Ethnicity_S_25" minOccurs="0"/>
                <xs:element ref="Education_V_2" minOccurs="0"/>
                <xs:element ref="EmploymentTrainingStatus_V_1" minOccurs="0"/>
                <xs:element ref="Type" minOccurs="0"/>
                <xs:element ref="PersonID" minOccurs="0"/>
                <xs:element ref="TypeName" minOccurs="0"/>
            </xs:all>
            <xs:attribute name="id" use="required" type="xs:integer"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="Forename" type="xs:string"/>
    <xs:element name="Surname" type="xs:string"/>
    <xs:element name="DateOfBirth" type="xs:NMTOKEN"/>
    <xs:element name="Gender" type="xs:string"/>
    <xs:element name="Address1" type="xs:string"/>
    <xs:element name="Address2" type="xs:string"/>
    <xs:element name="Town" type="xs:string"/>
    <xs:element name="County" type="xs:string"/>
    <xs:element name="Telephone" type="xs:string"/>
    <xs:element name="Mobile" type="xs:string"/>
    <xs:element name="Email" type="xs:string"/>
    <xs:element name="Created" type="xs:string"/>
    <xs:element name="CreatedBy" type="xs:NCName"/>
    <xs:element name="Updated" type="xs:string"/>
    <xs:element name="UpdatedBy" type="xs:NCName"/>
    <xs:element name="Archived" type="xs:string"/>
    <xs:element name="ArchivedBy" type="xs:string"/>
    <xs:element name="Postcode" type="xs:string"/>
    <xs:element name="Age" type="xs:integer"/>
    <xs:element name="RestrictedRecord" type="xs:integer"/>
    <xs:element name="Disability_S_24">
        <xs:complexType/>
  </xs:element>
    <xs:element name="Ethnicity_S_25">
        <xs:complexType/>
    </xs:element>
    <xs:element name="Type" type="xs:integer"/>
    <xs:element name="PersonID" type="xs:integer"/>
    <xs:element name="TypeName" type="xs:NCName"/>
</xs:schema>
4

3 に答える 3

2

2 つの兄弟要素が同じ名前を持つ場合、XSD (「要素宣言の一貫性」) には、それらも同じ型でなければならないという規則があります。

ただし、要素が兄弟としてではなく、XML 内の別の場所に表示される場合 (たとえば、スタッフ/スタッフと連絡先/スタッフ)、異なるタイプを持つことができます。これは、ローカル要素宣言を使用して実現できます。

于 2016-06-20T17:42:48.023 に答える
1

A. XSDとXML の両方を制御できる場合は、XML に異なるコンテンツ モデルを持つ 2 つの要素を含めるためのオプションを次に示します。staff

  1. 名前空間を使用してそれらを区別します。
  2. それらのいずれかの名前を変更します。

B. XSD を制御できても XML を制御できない場合は次のオプションがあります。

  1. ローカル定義を使用します。(グローバルに定義された 2 つの要素に同じ名前を付けることはできませんが、一方または両方がローカルに定義されていれば問題ありません。) [本当に同じ名前を使用したい場合は、推奨されます。]
  2. 2 つのコンテンツ モデルをマージして、共通のコンポーネントが必須になり、異なるコンポーネントがオプションになるようにします。(コンテキストによって 2 つのコンテンツ モデルが区別される場合は、必要に応じて XSD 1.1 アサーションを追加して区別を強化します。)

オプションB.1を使用して完全に修正された XSD を次に示します。

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           elementFormDefault="qualified">
  <xs:element name="contacts">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="staff"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="staff">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="staff" maxOccurs="unbounded">
          <xs:complexType>
            <xs:all>
              <xs:element ref="Forename" minOccurs="0"/>
              <xs:element ref="Surname" minOccurs="0"/>
              <xs:element ref="DateOfBirth" minOccurs="0"/>
              <xs:element ref="Gender" minOccurs="0"/>
              <xs:element ref="Address1" minOccurs="0"/>
              <xs:element ref="Address2" minOccurs="0"/>
              <xs:element ref="Town" minOccurs="0"/>
              <xs:element ref="County" minOccurs="0"/>
              <xs:element ref="Telephone" minOccurs="0"/>
              <xs:element ref="Mobile" minOccurs="0"/>
              <xs:element ref="Email" minOccurs="0"/>
              <xs:element ref="Created" minOccurs="0"/>
              <xs:element ref="CreatedBy" minOccurs="0"/>
              <xs:element ref="Updated" minOccurs="0"/>
              <xs:element ref="UpdatedBy" minOccurs="0"/>
              <xs:element ref="Archived" minOccurs="0"/>
              <xs:element ref="ArchivedBy" minOccurs="0"/>
              <xs:element ref="Postcode" minOccurs="0"/>
              <xs:element ref="Age" minOccurs="0"/>
              <xs:element ref="RestrictedRecord" minOccurs="0"/>
              <xs:element ref="Disability_S_24" minOccurs="0"/>
              <xs:element ref="Ethnicity_S_25" minOccurs="0"/>
              <xs:element ref="Education_V_2" minOccurs="0"/>
              <xs:element ref="EmploymentTrainingStatus_V_1" minOccurs="0"/>
              <xs:element ref="Type" minOccurs="0"/>
              <xs:element ref="PersonID" minOccurs="0"/>
              <xs:element ref="TypeName" minOccurs="0"/>
            </xs:all>
            <xs:attribute name="id" use="required" type="xs:integer"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
      <xs:attribute name="count" use="required" type="xs:integer"/>
      <xs:attribute name="pagesize" use="required" type="xs:integer"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Forename" type="xs:string"/>
  <xs:element name="Surname" type="xs:string"/>
  <xs:element name="DateOfBirth" type="xs:NMTOKEN"/>
  <xs:element name="Gender" type="xs:string"/>
  <xs:element name="Address1" type="xs:string"/>
  <xs:element name="Address2" type="xs:string"/>
  <xs:element name="Town" type="xs:string"/>
  <xs:element name="County" type="xs:string"/>
  <xs:element name="Telephone" type="xs:string"/>
  <xs:element name="Mobile" type="xs:string"/>
  <xs:element name="Email" type="xs:string"/>
  <xs:element name="Created" type="xs:string"/>
  <xs:element name="CreatedBy" type="xs:NCName"/>
  <xs:element name="Updated" type="xs:string"/>
  <xs:element name="UpdatedBy" type="xs:NCName"/>
  <xs:element name="Archived" type="xs:string"/>
  <xs:element name="ArchivedBy" type="xs:string"/>
  <xs:element name="Postcode" type="xs:string"/>
  <xs:element name="Age" type="xs:integer"/>
  <xs:element name="RestrictedRecord" type="xs:integer"/>
  <xs:element name="Disability_S_24">
    <xs:complexType/>
  </xs:element>
  <xs:element name="Ethnicity_S_25">
    <xs:complexType/>
  </xs:element>
  <xs:element name="Education_V_2">
    <xs:complexType/>
  </xs:element>
    <xs:element name="EmploymentTrainingStatus_V_1">
    <xs:complexType/>
  </xs:element>
  <xs:element name="Type" type="xs:integer"/>
  <xs:element name="PersonID" type="xs:integer"/>
  <xs:element name="TypeName" type="xs:NCName"/>
</xs:schema>

この XSD は XML を正常に検証します。

于 2016-06-20T13:13:18.593 に答える
1

あなたのフォーマットは私をそこから遠ざけました-私は最初にあなたの質問でそれを修正しましたが、あなたの質問に関連する詳細だと思うので気が変わりました. 実際には 2 つの兄弟要素はありませんstaff(終了タグを探していたときに気付きました)。親と同じ名前の子があります。それはいいです。再フォーマットされた XML は次のとおりです。

<contacts>
    <staff count="248" pagesize="284">
        <staff id="1231">
            <Forename>test</Forename>
            <Surname>test</Surname>
            <DateOfBirth>0000-00-00</DateOfBirth>
            <Gender/>
            <Address1/>
            <Address2/>
            <Town/>
            <County/>
            <Telephone/>
            <Mobile/>
            <Email/>
            <Created>0000-06-18 09:46:32</Created>
            <CreatedBy>test</CreatedBy>
            <Updated>2000-06-18 09:46:32</Updated>
            <UpdatedBy>test</UpdatedBy>
            <Archived>0000-00-00 00:00:00</Archived>
            <ArchivedBy/>
            <Postcode/>
            <Age>0</Age>
            <RestrictedRecord>0</RestrictedRecord>
            <Disability_S_24/>
            <Ethnicity_S_25/>
            <Type>8</Type>
            <PersonID>1231</PersonID>
            <TypeName>staff</TypeName>
        </staff>
    </staff>
</contacts>

とはいえ、現在の方法でスキーマを構築することはできません。考えてみてください。それはどのstaff要素をref参照しているのでしょうか? XSD パーサーは、それがどれであるかをどのように知ることができますか?

スキーマを修正する最も簡単な方法は、次のことだと思います。

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="contacts">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="staff"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="staff">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="staff" type="staffInner"/>
            </xs:sequence>
            <xs:attribute name="count" use="required" type="xs:integer"/>
            <xs:attribute name="pagesize" use="required" type="xs:integer"/>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="staffInner">
        <xs:all>
         ....

staffInnerもう少しコンテキストがあれば、より適切な名前を選択しindividualStaffMemberます。また、一貫性を保つために、代わりにrefa を使用するように他のものを変更することになるかもしれません。type

また、あなたは本当に欲しいxs:allのですxs:sequenceか?を保持するxs:allと、minOccurs="0"これらすべての子要素で が冗長になります。あなたが持っているつもりならxs:sequence(おそらくそうであると思います)、そこにそれが必要です-しかしxs:all、要素が任意の順序で表示されるようになるため、注意してください...

于 2016-06-20T17:48:45.407 に答える