W3C home > Mailing lists > Public > xmlschema-dev@w3.org > February 2020

Re: XSD with "required" attribute option related query

From: Loren Cahlander <loren.cahlander@gmail.com>
Date: Mon, 24 Feb 2020 10:50:45 -0500
Message-Id: <CA3BA671-001B-44C2-B465-652D85B095CE@gmail.com>
Cc: Loren Cahlander <loren.cahlander@gmail.com>, Mukul Gandhi <gandhi.mukul@gmail.com>, "xmlschema-dev@w3.org" <xmlschema-dev@w3.org>
To: Rajneesh Shukla <rajneeshshukla@gmail.com>
Take a look at the following:

<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://www.ascc.net/xml/schematron">
    <sch:pattern name="Check structure">
        <sch:rule context="Person">
            <sch:assert test="@Title">The element Person must have a Title attribute</sch:assert>
            <sch:assert test="count(*) = 2 and count(Name) = 1 and count(Gender) = 1">The element Person should have the child elements Name and Gender.</sch:assert>
            <sch:assert test="*[1] = Name">The element Name must appear before element Gender.</sch:assert>
        </sch:rule>
    </sch:pattern>
    <sch:pattern name="Check co-occurrence constraints">
        <sch:rule context="Person">
            <sch:assert test="(@Title = 'Mr' and Gender = 'Male') or @Title != 'Mr'">If the Title is "Mr" then the gender of the person must be "Male".</sch:assert>
        </sch:rule>
    </sch:pattern>
</sch:schema>

You will see that it does have constraints based on values.  Take a look at the article that I linked to.  It talks about those rules.

> On Feb 24, 2020, at 10:36 AM, Rajneesh Shukla <rajneeshshukla@gmail.com> wrote:
> 
> Thanks Loren,
> 
> One more expert advice please:
> Is it possible to impose required constraint at value level?
> 
> for example in below xml, I wnt to make sure value for alias1, coli1 and operator is always populated in condition element within where element.
> 
> 
> functionalView name="CLAIMS_FV"  description="Learning Purpose">
> 
>   <columns>
> 
>     <column name="CLAI.CODE"   columnAlias="CODE"  description="The code of the claim" />
> 
>     <column name="CLLI.CODE"   columnAlias="LINE_CODE"  description="The code of the claim line" />
> 
>     <column name="PROC.CODE"   columnAlias="PROC_CODE"  description="The code of the claim line procedure" />
> 
>   </columns>
> 
>   <fromviews>
> 
>     <fromview name="CLAIMS_V" alias="CLAI" />
> 
>     <fromview name="LINES_V" alias="CLLI" />
> 
>     <fromview name="PROC_V" alias="PROC" />
> 
>     <fromview name="PROV_V" alias="PROV" />
> 
>     <fromview name="FORMS_V" alias="CLFO"/>
> 
>     <fromview name="FORMTYPES_V" alias="CFTY"/>
> 
>   </fromviews>
> 
>   <joins>
> 
>     <join  alias1="CLLI" col1="CLAI_ID" condition="="  alias2="CLAI" col2="ID"/>
> 
>     <join  alias1="CLFO" col1="ID" condition="="  alias2="CFTY" col2="CLFO_ID"/>
> 
>     <join  alias1="CFTY" col1="ID" condition="="  alias2="PROC" col2="CFTY_ID"/>
> 
>     <leftouterjoin  alias1="PROV" col1="ID" condition="="  alias2="CLAI" col2="PROVIDER_ID"/>
> 
>   </joins>
> 
>   <where>
> 
>     <condition alias1="CFTY" col1="CODE"  operator="="  string=""   number="" date= ""    />
> 
>   </where>
> 
> </functionalView>
> 
> 
> Below is respective XSD for reference:
> 
> 
> <?xml version="1.0" encoding="UTF-8"?>
> 
> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema <http://www.w3.org/2001/XMLSchema>">
> 
>   <xs:element name="functionalView" >
> 
>     <xs:complexType>
> 
>       <xs:sequence>
> 
>         <xs:element name="columns">
> 
>           <xs:complexType>
> 
>             <xs:sequence>
> 
>               <xs:element name="column" maxOccurs="unbounded" minOccurs="1">
> 
>                 <xs:complexType>
> 
>                   <xs:simpleContent>
> 
>                     <xs:extension base="xs:string">
> 
>                       <xs:attribute type="xs:string" name="name" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="columnAlias" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="description" use="required"/>
> 
>                     </xs:extension>
> 
>                   </xs:simpleContent>
> 
>                 </xs:complexType>
> 
>               </xs:element>
> 
>             </xs:sequence>
> 
>           </xs:complexType>
> 
>         </xs:element>
> 
>         <xs:element name="fromviews" maxOccurs="1" minOccurs="1">
> 
>           <xs:complexType>
> 
>             <xs:sequence>
> 
>               <xs:element name="fromview" maxOccurs="unbounded" minOccurs="2">
> 
>                 <xs:complexType>
> 
>                   <xs:simpleContent>
> 
>                     <xs:extension base="xs:string">
> 
>                       <xs:attribute type="xs:string" name="name" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="alias" use="required"/>
> 
>                     </xs:extension>
> 
>                   </xs:simpleContent>
> 
>                 </xs:complexType>
> 
>               </xs:element>
> 
>             </xs:sequence>
> 
>           </xs:complexType>
> 
>         </xs:element>
> 
>         <xs:element name="joins" maxOccurs="1" minOccurs="1">
> 
>           <xs:complexType>
> 
>             <xs:choice maxOccurs="unbounded" minOccurs="1">
> 
>               <xs:element name="join" maxOccurs="unbounded" minOccurs="0">
> 
>                 <xs:complexType>
> 
>                   <xs:simpleContent>
> 
>                     <xs:extension base="xs:string">
> 
>                       <xs:attribute type="xs:string" name="alias1" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="col1" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="condition" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="alias2" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="col2" use="required"/>
> 
>                     </xs:extension>
> 
>                   </xs:simpleContent>
> 
>                 </xs:complexType>
> 
>               </xs:element>
> 
>               <xs:element name="leftouterjoin" maxOccurs="unbounded" minOccurs="0">
> 
>                 <xs:complexType>
> 
>                   <xs:simpleContent>
> 
>                     <xs:extension base="xs:string">
> 
>                       <xs:attribute type="xs:string" name="alias1" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="col1" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="condition" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="alias2" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="col2" use="required"/>
> 
>                     </xs:extension>
> 
>                   </xs:simpleContent>
> 
>                 </xs:complexType>
> 
>               </xs:element>
> 
>             </xs:choice>
> 
>           </xs:complexType>
> 
>         </xs:element>
> 
>         <xs:element name="where" maxOccurs="1" minOccurs="0">
> 
>           <xs:complexType>
> 
>             <xs:sequence>
> 
>               <xs:element name="condition" maxOccurs="unbounded" minOccurs="1">
> 
>                 <xs:complexType>
> 
>                   <xs:simpleContent>
> 
>                     <xs:extension base="xs:string">
> 
>                       <xs:attribute type="xs:string" name="alias1" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="col1" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="operator" use="required"/>
> 
>                       <xs:attribute type="xs:string" name="string" use="optional"/>
> 
>                       <xs:attribute type="xs:string" name="number" use="optional"/>
> 
>                       <xs:attribute type="xs:string" name="date" use="optional"/>
> 
>                     </xs:extension>
> 
>                   </xs:simpleContent>
> 
>                 </xs:complexType>
> 
>               </xs:element>
> 
>             </xs:sequence>
> 
>           </xs:complexType>
> 
>         </xs:element>
> 
>       </xs:sequence>
> 
>       <xs:attribute type="xs:string" name="name"/>
> 
>       <xs:attribute type="xs:string" name="description"/>
> 
>     </xs:complexType>
> 
>   </xs:element>
> 
> </xs:schema>
> 
> 
> 
> Thanks,
> 
> Rajneesh
> 
> 
> On Mon, 24 Feb 2020 at 20:57, Loren Cahlander <loren.cahlander@gmail.com <mailto:loren.cahlander@gmail.com>> wrote:
> If you cannot use XSD 1.1, then I would recommend that you utilize Schematron.
> 
> https://www.xml.com/pub/a/2003/11/12/schematron.html <https://www.xml.com/pub/a/2003/11/12/schematron.html>
> 
>> On Feb 24, 2020, at 10:00 AM, Rajneesh Shukla <rajneeshshukla@gmail.com <mailto:rajneeshshukla@gmail.com>> wrote:
>> 
>> Hi Mukul,
>> 
>> One more help please:
>> 
>> Is it possible to impose required constraint at value level?
>> for example in below xml, I wnt to make sure value for alias1, coli1 and operator is always populated in condition element within where element.
>> 
>> functionalView name="CLAIMS_FV"  description="Learning Purpose">
>> 
>>   <columns>
>> 
>>     <column name="CLAI.CODE"   columnAlias="CODE"  description="The code of the claim" />
>> 
>>     <column name="CLLI.CODE"   columnAlias="LINE_CODE"  description="The code of the claim line" />
>> 
>>     <column name="PROC.CODE"   columnAlias="PROC_CODE"  description="The code of the claim line procedure" />
>> 
>>   </columns>
>> 
>>   <fromviews>
>> 
>>     <fromview name="CLAIMS_V" alias="CLAI" />
>> 
>>     <fromview name="LINES_V" alias="CLLI" />
>> 
>>     <fromview name="PROC_V" alias="PROC" />
>> 
>>     <fromview name="PROV_V" alias="PROV" />
>> 
>>     <fromview name="FORMS_V" alias="CLFO"/>
>> 
>>     <fromview name="FORMTYPES_V" alias="CFTY"/>
>> 
>>   </fromviews>
>> 
>>   <joins>
>> 
>>     <join  alias1="CLLI" col1="CLAI_ID" condition="="  alias2="CLAI" col2="ID"/>
>> 
>>     <join  alias1="CLFO" col1="ID" condition="="  alias2="CFTY" col2="CLFO_ID"/>
>> 
>>     <join  alias1="CFTY" col1="ID" condition="="  alias2="PROC" col2="CFTY_ID"/>
>> 
>>     <leftouterjoin  alias1="PROV" col1="ID" condition="="  alias2="CLAI" col2="PROVIDER_ID"/>
>> 
>>   </joins>
>> 
>>   <where>
>> 
>>     <condition alias1="CFTY" col1="CODE"  operator="="  string=""   number="" date= ""    />
>> 
>>   </where>
>> 
>> </functionalView>
>> 
>> Thanks,
>> Rajneesh
>> 
>> On Mon, 24 Feb 2020 at 13:39, Rajneesh Shukla <rajneeshshukla@gmail.com <mailto:rajneeshshukla@gmail.com>> wrote:
>> Hi Mukul,
>> 
>> Thanks for your reply.
>> I am  working inside the database, it won't be possible.
>> 
>> Oracle XML DB only supports XML Schema 1.0.
>> 
>> 
>> 
>> Thanks,
>> 
>> Rajneesh
>> 
>> 
>> On Sat, 22 Feb 2020 at 11:27, Mukul Gandhi <gandhi.mukul@gmail.com <mailto:gandhi.mukul@gmail.com>> wrote:
>> Hi Rajneesh,
>>     Within the XSD document you've attached, following is a XSD issue to start with (using Xerces-J 2.12.1 as XSD validator),
>> 
>> [Error] query1.xsd:3:67: s4s-att-not-allowed: Attribute 'maxOccurs' cannot appear in element 'element'.
>> [Error] query1.xsd:3:67: s4s-att-not-allowed: Attribute 'minOccurs' cannot appear in element 'element'.
>> 
>> i.e, the following is not allowed by XSD language,
>> 
>> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema <http://www.w3.org/2001/XMLSchema>">
>> 
>>     <xs:element name="functionalView" maxOccurs="1" minOccurs="1">
>>     ...
>> 
>> </xs:schema>
>> 
>> Removing, maxOccurs="1" minOccurs="1" from above shown xs:element declaration from your attached XSD document, makes your XSD document correct (with both 1.0 and 1.1 versions of XSD language).
>> 
>> Now coming to your question.
>> I think that, the issue you've mentioned can be solved using an XSD 1.1 <assert> instruction. I guess that, you can rewrite your XSD fragment to following (I've only added an <assert>), to achieve what you've mentioned,
>> 
>> <xs:element name="where" maxOccurs="1" minOccurs="0">
>>        <xs:complexType>
>>              <xs:sequence>
>>                    <xs:element name="condition" maxOccurs="unbounded" minOccurs="1">
>>                          <xs:complexType>
>>                                <xs:simpleContent>
>>                                      <xs:extension base="xs:string">
>>                                             <xs:attribute type="xs:string" name="alias1" use="required"/>
>>                                             <xs:attribute type="xs:string" name="col1" use="required"/>
>>                                             <xs:attribute type="xs:string" name="operator" use="required"/>
>>                                             <xs:attribute type="xs:string" name="string" use="optional"/>
>>                                             <xs:attribute type="xs:string" name="number" use="optional"/>
>>                                             <xs:attribute type="xs:string" name="date" use="optional"/>
>>                                             <xs:assert test="exists(@string | @number | @date)"/>
>>                                    </xs:extension>
>>                               </xs:simpleContent>
>>                          </xs:complexType>
>>                      </xs:element>
>>                 </xs:sequence>
>>          </xs:complexType>
>> </xs:element>
>> 
>> I've not tested, the logic of <assert> I've mentioned above.
>> 
>> Could be useful information to share that, you may use the full XPath 2.0 language, to write value of 'test' attribute of an <assert>. Also, 1 upto any number of <assert> elements can be written as siblings in the XSD document (all of the sibling <assert> elements, have to evaluate to true for having the XML instance document valid).
>> 
>> On Fri, Feb 21, 2020 at 11:16 PM Rajneesh Shukla <rajneeshshukla@gmail.com <mailto:rajneeshshukla@gmail.com>> wrote:
>> Hello All,
>> 
>> I am new to XSD and XML and need to explore if there is option to make sure that any one attribute in a set of attributes within same element is required.
>> 
>> Example:
>> 
>>   <xs:element name="where" maxOccurs="1" minOccurs="0">
>>           <xs:complexType>
>>             <xs:sequence>
>>               <xs:element name="condition" maxOccurs="unbounded" minOccurs="1">
>>                 <xs:complexType>
>>                   <xs:simpleContent>
>>                     <xs:extension base="xs:string">
>>                       <xs:attribute type="xs:string" name="alias1" use="required"/>
>>                       <xs:attribute type="xs:string" name="col1" use="required"/>
>>                       <xs:attribute type="xs:string" name="operator" use="required"/>
>>                       <xs:attribute type="xs:string" name="string" use="optional"/>
>>                       <xs:attribute type="xs:string" name="number" use="optional"/>
>>                       <xs:attribute type="xs:string" name="date" use="optional"/>
>>                     </xs:extension>
>>                   </xs:simpleContent>
>>                 </xs:complexType>
>>               </xs:element>
>>             </xs:sequence>
>>           </xs:complexType>
>>         </xs:element>
>> 
>> Here I want to ensure that minimum one  attribute  in a set of 3 attributes (mentioned as optional in above) are required. All can not be optional , however any one (can be more than one also) is required.
>> 
>> Thanking you in anticipation !!!
>> 
>> Attachment:
>> Complete XSD file.
>> 
>> 
>> 
>> --
>> Regards,
>> Mukul Gandhi
> 


Received on Monday, 24 February 2020 15:51:05 UTC

This archive was generated by hypermail 2.4.0 : Monday, 24 February 2020 15:51:05 UTC