我有以下XML代码:
<?xml version="1.0" encoding="UTF-8"?>
<!--<!DOCTYPE bank SYSTEM "bank.dtd">-->
<bank xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="bank.xsd">
<accounts>
<savings_accounts>
<savings_account id="a1" interest="0.03">
<balance>2500</balance>
</savings_account>
<savings_account id="a2" interest="0.03">
<balance>15075</balance>
</savings_account>
</savings_accounts>
<checking_accounts>
<checking_account id="a3">
<balance>4025</balance>
</checking_account>
<checking_account id="a4">
<balance>-125</balance>
</checking_account>
<checking_account id="a5">
<balance>325</balance>
</checking_account>
</checking_accounts>
</accounts>
<customers>
<customer id="c1">
<name>Ben Richerdson</name>
<address>Park Drive 2</address>
</customer>
<customer id="c2">
<name>Marc Wretcher</name>
<address>Mill Drive 75</address>
</customer>
<customer id="c3">
<name>Angel Steady</name>
<address>Lake Sight 15</address>
</customer>
</customers>
<customer_accounts>
<customer_account c_id="c1" ac_id="a2"/>
<customer_account c_id="c1" ac_id="a3"/>
<customer_account c_id="c2" ac_id="a4"/>
<customer_account c_id="c3" ac_id="a1"/>
<customer_account c_id="c3" ac_id="a5"/>
</customer_accounts>
</bank>
我还为XML编写了适当的XSD架构,如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bank">
<xs:complexType>
<xs:sequence>
<xs:element name="accounts">
<xs:complexType>
<xs:sequence>
<xs:element name="savings_accounts">
<xs:complexType>
<xs:sequence>
<xs:element name="savings_account" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="balance">
<xs:simpleType>
<xs:restriction base="xs:double">
<xs:minInclusive value="-5000"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="interest" type="xs:double" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="onesavings_accountforEachid">
<xs:selector xpath="xs:savings_account"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
<xs:element name="checking_accounts">
<xs:complexType>
<xs:sequence>
<xs:element name="checking_account" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="balance">
<xs:simpleType>
<xs:restriction base="xs:double">
<xs:minInclusive value="-5000"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="onechecking_accountforEachid">
<xs:selector xpath="xs:checking_account"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="customers">
<xs:complexType>
<xs:sequence>
<xs:element name="customer" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="onecustomerforEachid">
<xs:selector xpath="xs:customer"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
<xs:element name="customer_accounts">
<xs:complexType>
<xs:sequence>
<xs:element name="customer_account" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="c_id" type="xs:string" use="required"/>
<xs:attribute name="ac_id" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
所以我的问题是,如何将customer_account的c_id =“c1”和ac_id =“a2”引用到帐户中定义的相应ID。 'c_id'表示客户,'ac_id'表示帐户。
我认为可以做同样的事情,但我必须添加id作为元素,并将它们定义为私钥和后来的外键。
感谢您的帮助!
答案 0 :(得分:2)
我认为你正在寻找一种方法来确保
customer_account/@c_id
的每个值,只有一个客户将该值作为其@id属性的值。customer_account/@ac_id
的每个值,只有一个帐户(支票或储蓄帐户),该值为其@id属性的值。最后三个约束已经包含在元素unique
,savings_accounts
和checking_accounts
中的customers
元素中。
如果这是对你想要达到的目标的正确理解,那么:
如果您想确保customer_account/@ac_id
的任何值只与一个帐户匹配,则需要确保没有支票帐户与任何储蓄帐户具有相同的ID。现在,您允许储蓄和支票帐户共享ID。您需要在unique
上添加涵盖两种帐户形式的key
(或accounts
)约束。以下应该这样做:
<xs:unique name="oneaccountforEachid">
<xs:selector xpath="*/*"/>
<xs:field xpath="@id"/>
</xs:unique>
您希望定义两个keyref
元素,指定元素customer_account
上的c_id和a_id属性成功引用客户和帐户的键。如果您愿意,可以使用customer_account
元素:
<xs:keyref refer="onecustomerforEachid"
name="ca_customer_pointer" >
<xs:selector xpath="."/>
<xs:field xpath="@c_id"/>
</xs:keyref>
<xs:keyref refer="oneaccountforEachid"
name="ca_account_pointer">
<xs:selector xpath="."/>
<xs:field xpath="@ac_id"/>
</xs:keyref>
对我自己说,如果所有身份约束都在bank
元素上,我认为架构可能会更清晰:
<xs:element name="bank" type="bank">
<xs:unique name="account_id_unique">
<xs:selector xpath="accounts/*/*"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:unique name="customer_id_unique">
<xs:selector xpath="customers/customer"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:keyref name="ca_customer_id"
refer="customer_id_unique">
<xs:selector
xpath="customer_accounts/customer_account"/>
<xs:field xpath="@c_id"/>
</xs:keyref>
<xs:keyref name="ca_account_id"
refer="account_id_unique">
<xs:selector
xpath="customer_accounts/customer_account"/>
<xs:field xpath="@ac_id"/>
</xs:keyref>
</xs:element>
此外,您可能希望将现有的unique
元素更改为key
元素,以强调每个客户和帐户都需要具有@id。差异的一个简短描述是:您拥有的unique
约束(或显示的那些)表示如果指定元素上出现@id属性,则其值必须在这些元素的@id值中唯一。 key
约束需要相同的内容,并且还要求所有相关元素实际上具有 @id属性。由于您已经需要@id属性(通过其声明),因此在这种情况下两者具有相同的效果。