XML DTD必需属性选项

时间:2013-11-22 12:56:36

标签: xml dtd

我正在尝试为以下元素构建DTD(作为完整XML文件的更大DTD的一部分):

<contact>
        <base>019374627</base>
        <mobile primaryContact="true">0861029388</phone>
        <email>john@lennon.com</email>
</contact>

我很困惑,因为这个contact元素必须包含至少一个元素,并且contact中必须只有一个元素具有primaryContact="true"属性。

如何用DTD表示?任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

这不能用DTD表示。

在DTD中,您可以指定contact元素必须包含mobile元素。您还可以指定特定子元素(例如mobile)必须具有primaryContact属性,其(固定)值为“true”。

但是不可能只声明一个元素必须至少有一个子元素,或者primaryContact属性必须只出现在一个子元素上。必须显式声明所有允许的子元素。元素的有效性不能依赖于附加到另一个元素的属性。

FWIW,约束可以Schematron架构表示:

<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">

  <sch:pattern name="Check children of 'contact'">
    <sch:rule context="contact"> 
      <sch:assert test="*">
        'contact' must contain at least one element
      </sch:assert>
      <sch:assert test="count(*[@primaryContact='true']) = 1">
        'contact' must contain exactly one element where @primaryContact='true'
      </sch:assert>
    </sch:rule>
  </sch:pattern>

</sch:schema>

答案 1 :(得分:1)

您的DTD略有不同,您可能能够表达您的需求。我们的想法是将所需内容包装在新的元素中。这允许您在contact上指定它需要有一个primary元素:

<contact>
    <primary><mobile>0861029388</mobile></primary>
    <base>019374627</base>
    <email>john@lennon.com</email>
</contact>

您的DTD可能如下所示:

<!ELEMENT contact (primary, (mobile|base|email)*)>
<!ELEMENT primary (mobile|base|email)+>
<!ELEMENT mobile (#PCDATA)>
<!ELEMENT base (#PCDATA)>
<!ELEMENT email (#PCDATA)>

或者,为了减少冗余并提高可维护性:

<!ENTITY % contact_field "mobile|base|email" >
<!ELEMENT contact (primary, (%contact_field;)*)>
<!ELEMENT primary (%contact_field;)+>
<!ELEMENT mobile (#PCDATA)>
<!ELEMENT base (#PCDATA)>
<!ELEMENT email (#PCDATA)>