Можно ли связать атрибут с другим в XSD?

#xml #xsd

#xml #xsd

Вопрос:

Могу ли я сделать c_id ссылку на <customers> и ac_id ссылаться на <accounts> , что означает ограничение области действия c_id на id <savings_account> и ac_id на id <checking_account> ?

 <?xml version="1.0" encoding="UTF-8"?>
<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>
  

Комментарии:

1. Это возможно в XSD-1.1. Но где ваш XSD? Пожалуйста, предоставьте XSD, насколько у вас есть при разработке решения.

Ответ №1:

Это возможно только в XSD-1.1. Вы можете использовать файл XSD-1.1, как показано ниже. Он использует три xsd:assert s для реализации желаемых ограничений (или несколько близких к вашим требованиям):

 <?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="bank">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="accounts" />          
                <xs:element ref="customers" />          
                <xs:element ref="customer_accounts" />    
            </xs:sequence>
            <xs:assert test="every $c in customers/customer satisfies $c/@id = customer_accounts/customer_account/@c_id" />
            <xs:assert test="every $a in accounts/savings_accounts/savings_account  satisfies $a/@id = customer_accounts/customer_account/@ac_id" /> 
            <xs:assert test="every $a2 in accounts/checking_accounts/checking_account  satisfies $a2/@id = customer_accounts/customer_account/@ac_id" />
        </xs:complexType>
    </xs:element>
          
    <xs:element name="accounts">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="savings_accounts" />          
                <xs:element ref="checking_accounts" />          
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="savings_accounts">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="savings_account">
                <xs:complexType>
                    <xs:sequence>
                    <xs:element name="balance" type="xs:unsignedShort" />
                    </xs:sequence>
                    <xs:attribute name="id" type="xs:string" use="required" />
                    <xs:attribute name="interest" type="xs:decimal" use="required" />
                </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
        
    <xs:element name="checking_accounts">
        <xs:complexType>
            <xs:sequence>
            <xs:element maxOccurs="unbounded" name="checking_account">
                <xs:complexType>
                <xs:sequence>
                    <xs:element name="balance" type="xs:short" />
                </xs:sequence>
                <xs:attribute name="id" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
                            
    <xs:element name="customers">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="customer">
                    <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:element>
    
    <xs:element name="customer_accounts">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="customer_account">
                    <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:schema>
  

Первый из них

 every $c in customers/customer satisfies $c/@id = customer_accounts/customer_account/@c_id
  

утверждает, что каждый <customer> атрибут ‘s id содержится как атрибут <customer_account ‘s c_id .

Второй из них

 every $a in accounts/savings_accounts/savings_account satisfies $a/@id = customer_accounts/customer_account/@ac_id
  

утверждает, что каждый <savings_account> атрибут ‘s id содержится как атрибут <customer_account ‘s ac_id .

Третий

 every $a2 in accounts/checking_accounts/checking_account  satisfies $a2/@id = customer_accounts/customer_account/@ac_id
  

утверждает, что каждый <checking_account> атрибут ‘s id содержится как атрибут <customer_account ‘s ac_id .

Так что да, это возможно

свяжите атрибут с другим атрибутом в XSD