我正在尝试为以下元素构建DTD(作为完整XML文件的更大DTD的一部分):
<contact>
<base>019374627</base>
<mobile primaryContact="true">0861029388</phone>
<email>john@lennon.com</email>
</contact>
我很困惑,因为这个contact
元素必须包含至少一个元素,并且contact
中必须只有一个元素具有primaryContact="true"
属性。
如何用DTD表示?任何帮助将不胜感激!
答案 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)>