What attlist statement would I use for a second attribute that only shows up if a certain first attribute is selected?

StackOverflow https://stackoverflow.com/questions/18926547

  •  29-06-2022
  •  | 
  •  

Question

Right now I am trying to make it so I validate a second attribute of checknum in payment only when the first attribute selected is check. Here is some xml examples

Payment without check selected

 <payment type="transfer" >
      <to category="utilities">Central Electric</to>
      <amount>94.85</amount>
      <date>2005-08-29</date>
      <description>Electric Bill</description>
   </payment>

Payment with check selected

<payment type="check" checknum="C1213">
      <to category="food">Pizza Now</to>
      <amount>33.24</amount>
      <date>2005-08-28</date>
      <description>Dinner</description>
   </payment>

What type of attlist statement would I put to specifically say that check must have checknum but not for all the other selections?

I was thinking on the lines of something like this

<!ELEMENT payment  (to,amount,date,description)>    
<!ATTLIST payment type (check | transfer | atm) "check" >
<!ATTLIST payment type (check)  checknum >

But of course the third line is not valid.

Était-ce utile?

La solution

This is how I understand the question. The <payment> element has a type attribute. If the attribute value is "check", then there must also be a checknum attribute on that element. How do I enforce this in the DTD?

Constraints on attributes and elements based on the value or occurrence of other elements and attributes is often called "co-occurrence constraints". This cannot be expressed in a DTD. There is no ATTLIST syntax for your requirement. So the answer is: it is not possible.

But you can do it with RELAX NG. Here is a RELAX NG schema with two possible content models for the payment element that only differ in the treatment of the type attribute:

start = payment1 | payment2

payment1 = element payment { attribute type { "check" }, attribute checknum { text }, 
                             to, amount, date, description }
payment2 = element payment { attribute type { "transfer" | "atm" }, 
                             to, amount, date, description }

to = element to { attribute category { text }, text}
amount = element amount { xsd:float }
date = element date { xsd:date }
description = element description { text }

Test document to validate:

<payment type="check">
  <to category="food">Pizza Now</to>
  <amount>33.24</amount>
  <date>2005-08-28</date>
  <description>Dinner</description>
</payment>

When checked by Jing, the result is this:

$ java -jar jing.jar -c payment.rnc payment.xml
payment.xml:1:23: error: element "payment" missing required attribute "checknum"

There is a section on co-occurrence constraints in the book "RELAX NG" by Eric van der Vlist. Here is a quote:

While co-occurrence constraints provide powerful capabilities, they unfortunately don't survive conversion to DTDs or W3C XML Schema.

Since that was written (about 10 years ago, I guess), W3C XML Schema has been augmented with new features in this area (see http://www.ibm.com/developerworks/xml/library/x-xml11pt2/index.html). But the capabilities of DTDs have not improved.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top