为具有相同名称的元素创建XML模式?

时间:2016-06-20 12:50:41

标签: xml xsd jitterbit

我正在尝试为我收到的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>

3 个答案:

答案 0 :(得分:2)

如果两个兄弟元素具有相同的名称,那么XSD中的规则(&#34;元素声明一致&#34;)表明它们必须具有相同的类型。

但是,如果元素出现在XML的不同位置,而不是兄弟姐妹(例如员工/员工与联系人/员工),那么他们可以有不同的类型;这可以使用局部元素声明来实现。

答案 1 :(得分:1)

A。如果您可以控制 XSD XML,这里有两个staff元素在XML中具有不同内容模型的选项:

  1. 使用命名空间来区分它们。
  2. 重命名其中一个。
  3. B。如果您可以控制XSD 而不是 XML,可以选择以下选项:

    1. 使用本地定义。 (两个全局定义的元素不能具有相同的名称,但如果其中一个或两个都是本地定义的,那就很好。)[推荐,如果您真的想使用相同的名称。]
    2. 合并两个内容模型,以便需要共同的组件,并且不同的组件是可选的。 (如果上下文区分了两个内容模型,可以选择添加XSD 1.1断言来强制区分。)
    3. 以下是使用选项 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。

答案 2 :(得分:0)

你的格式告诉了我 - 我最初在你的问题中纠正了它,但改变了我的想法,因为我认为这是你问题的相关细节。你实际上并没有两个兄弟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以使用type来保持一致性。

此外,您确定要xs:all而不仅仅是xs:sequence吗?如果您保留xs:all,则minOccurs="0"在所有这些子元素上都是多余的。如果你的意思是xs:sequence(我怀疑可能是这种情况),你确实需要它 - 但要注意,因为xs:all将允许元素以任何顺序出现...... < / p>