使用 DTD 限制只有一个元素具有特定属性

Restrict that only one element has a specific attribute with DTD

这是我需要用 DTD 验证的 xml 文件:

<branch state="hessen">
    <city>Marburg</city>
    <headquarter/>
    <staff manager="yes">Egon</staff>
    <staff manager="no">Erna</staff>
    <staff manager="no">Claudia</staff>
</branch>

问题是每个分支机构只允许一名经理。现在的任务是用 DTD 文件来限制它,但我现在不知道如何去做。

这是我目前得到的:

 <!ELEMENT insurance (branch*)>
            <!ELEMENT branch (city,zentrale?,(staff,staff+))>
            <!ATTLIST branch
                    state ID #REQUIRED
            >
            <!ELEMENT city (#PCDATA)>
            <!ELEMENT headquarter EMPTY>
            <!ELEMENT staff (#PCDATA)>
            <!ATTLIST staff
                    manager (yes|no) #REQUIRED
            >

我现在如何实施该限制?

您将无法使用 DTD 强制执行该规则。

我同意 Michael Kay 关于使用 XML Schema 1.1 的建议。

您可以使用 xs:assert 来执行规则。

示例...

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
  xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <xs:element name="branch">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="city"/>
        <xs:element ref="headquarter"/>
        <xs:element maxOccurs="unbounded" ref="staff"/>        
      </xs:sequence>
      <xs:attribute name="state" use="required" type="xs:NCName"/>
      <xs:assert test="count(staff[@manager='yes']) le 1"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="city" type="xs:NCName"/>

  <xs:element name="headquarter">
    <xs:complexType/>
  </xs:element>

  <xs:element name="staff">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:NCName">
          <xs:attribute name="manager" use="required" type="xs:NCName"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
</xs:schema>

您也可以使用 Schematron 或 XSLT 进行规则检查。