XSD 模式的属性来引用其他元素属性的唯一性
Attributes of XSD schema to referee unique ides of other element attributes
我有以下 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>
所以我的问题是,如何将 c_id="c1" 和 customer_account 的 c_id="a2" 引用到适当的 ID 作为在帐户中定义。 'c_id' 指客户,'ac_id' 指帐户。
我在寻找是否可以做同样的事情,但我必须添加 id 作为元素并将它们定义为私钥和后来的外键。
感谢您的帮助!
我想你是在寻求一种方法来确保
- 对于属性
customer_account/@c_id
的每个值,只有一个客户将该值作为其 @id 属性的值。
- 对于属性
customer_account/@ac_id
的每个值,只有一个帐户(支票帐户或储蓄帐户)具有该值作为其 @id 属性的值。
- 没有两个客户具有相同的@id 值。
- 没有两个储蓄账户具有相同的@id 值。
- 没有两个支票帐户具有相同的@id 值。
您在元素 savings_accounts
、checking_accounts
和 customers
.
中包含的 unique
元素已强制执行最后三个约束
如果这是对您要实现的目标的正确理解,那么:
如果要确保 customer_account/@ac_id
的任何值都与一个帐户完全匹配,则需要确保没有支票帐户与任何储蓄帐户具有相同的 ID。现在,您允许储蓄和支票账户共享 ID。您需要在涵盖两种帐户形式的 accounts
上添加 unique
(或 key
)限制条件。以下应该这样做:
<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 属性(通过其声明),因此在这种情况下两者具有相同的效果。
我有以下 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>
所以我的问题是,如何将 c_id="c1" 和 customer_account 的 c_id="a2" 引用到适当的 ID 作为在帐户中定义。 'c_id' 指客户,'ac_id' 指帐户。
我在寻找是否可以做同样的事情,但我必须添加 id 作为元素并将它们定义为私钥和后来的外键。
感谢您的帮助!
我想你是在寻求一种方法来确保
- 对于属性
customer_account/@c_id
的每个值,只有一个客户将该值作为其 @id 属性的值。 - 对于属性
customer_account/@ac_id
的每个值,只有一个帐户(支票帐户或储蓄帐户)具有该值作为其 @id 属性的值。 - 没有两个客户具有相同的@id 值。
- 没有两个储蓄账户具有相同的@id 值。
- 没有两个支票帐户具有相同的@id 值。
您在元素 savings_accounts
、checking_accounts
和 customers
.
unique
元素已强制执行最后三个约束
如果这是对您要实现的目标的正确理解,那么:
如果要确保
customer_account/@ac_id
的任何值都与一个帐户完全匹配,则需要确保没有支票帐户与任何储蓄帐户具有相同的 ID。现在,您允许储蓄和支票账户共享 ID。您需要在涵盖两种帐户形式的accounts
上添加unique
(或key
)限制条件。以下应该这样做:<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 属性(通过其声明),因此在这种情况下两者具有相同的效果。