3

我正在尝试为收到的 XML 文档创建 XSD 架构,但是有两个元素staff具有相同的名称。

即使有两个同名的元素,是否有任何方法可以为此 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

如果两个同级元素具有相同的名称,则 XSD 中有一条规则(“元素声明一致”)规定它们也必须具有相同的类型。

但是,如果元素出现在 XML 中的不同位置,而不是作为同级出现(例如员工/员工与联系人/员工),那么它们可以具有不同的类型;这可以使用本地元素声明来实现。

于 2016-06-20T17:42:48.023 回答
1

你的格式让我失望了——我最初在你的问题中纠正了它,但我改变了主意,因为我认为这是你问题的相关细节。您实际上并没有两个兄弟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?我也可能最终改变你的另一个ref来使用 atype来保持一致性。

另外,你确定你想要xs:all而不只是xs:sequence?如果保留xs:allminOccurs="0"则所有这些子元素都是多余的。如果你打算拥有xs:sequence(我怀疑可能是这种情况),你确实需要它 - 但要小心,因为xs:all它将允许元素以任何顺序出现......

于 2016-06-20T17:48:45.407 回答
1

A.如果您可以同时控制XSDXML,以下是staff在您的 XML 中包含两个具有不同内容模型的元素的选项:

  1. 使用命名空间来区分它们。
  2. 重命名其中之一。

B.如果您可以控制 XSD不能控制XML,这里有一些选项:

  1. 使用本地定义。(两个全局定义的元素不能具有相同的名称,但是如果一个或两个都在本地定义就可以了。)[推荐,如果你真的想使用相同的名称。]
  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 回答