现在我正在尝试这样做,所以只有当选中的第一个属性被检查时,才会在付款时验证checknum的第二个属性。这是一些xml示例
未选中支票的付款
<payment type="transfer" >
<to category="utilities">Central Electric</to>
<amount>94.85</amount>
<date>2005-08-29</date>
<description>Electric Bill</description>
</payment>
选中支票付款
<payment type="check" checknum="C1213">
<to category="food">Pizza Now</to>
<amount>33.24</amount>
<date>2005-08-28</date>
<description>Dinner</description>
</payment>
我会说什么类型的attlist陈述专门说支票必须有checknum但不适用于所有其他选择?
我正在思考像这样的事情
<!ELEMENT payment (to,amount,date,description)>
<!ATTLIST payment type (check | transfer | atm) "check" >
<!ATTLIST payment type (check) checknum >
但当然第三行无效。
答案 0 :(得分:1)
这就是我理解这个问题的方法。 <payment>
元素具有type
属性。如果属性值为“check”,则该元素上还必须有checknum
属性。如何在DTD中强制执行此操作?
基于其他元素和属性的值或出现的对属性和元素的约束通常称为“共现约束”。这不能用DTD表示。您的要求没有ATTLIST
语法。所以答案是:这是不可能的。
但你可以用RELAX NG来做。这是一个RELAX NG模式,其中包含payment
元素的两种可能内容模型,这些模型仅在type
属性的处理方面有所不同:
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 }
要验证的测试文档:
<payment type="check">
<to category="food">Pizza Now</to>
<amount>33.24</amount>
<date>2005-08-28</date>
<description>Dinner</description>
</payment>
经Jing检查后,结果如下:
$ java -jar jing.jar -c payment.rnc payment.xml
payment.xml:1:23: error: element "payment" missing required attribute "checknum"
Eric van der Vlist的书“RELAX NG”中有a section on co-occurrence constraints。这是一个引用:
虽然共现约束提供了强大的功能,但遗憾的是它们无法转换为DTD或W3C XML Schema。
由于这是写的(大约10年前,我猜),W3C XML Schema已经增加了该领域的新功能(参见http://www.ibm.com/developerworks/xml/library/x-xml11pt2/index.html)。但是DTD的功能并没有得到改善。