2013-11-22 60 views
1

我試圖構建以下元素的DTD(作爲一個完整的XML文件較大DTD的一部分):XML DTD強制屬性選項

<contact> 
     <base>019374627</base> 
     <mobile primaryContact="true">0861029388</phone> 
     <email>[email protected]</email> 
</contact> 

我只是困惑,因爲這contact元素必須至少包含一個元素,並且contact內必須只有一個元素具有primaryContact="true"屬性。

這怎麼可能用DTD表示?任何幫助將不勝感激!

回答

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

有輕微的變化,你DTD,那麼你也許可以表達你所需要的。這個想法是將所需的內容包裝在一個新的元素中。這允許您指定contact,它需要有一個primary元素:

<contact> 
    <primary><mobile>0861029388</mobile></primary> 
    <base>019374627</base> 
    <email>[email protected]</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)>