Make XML elements required based on attribute values in XSD -
my requirement have xsd file checks elements based on attribute values. able write xsd point can restrict attribute values of application/@type
. can me complete xsd file can make elements required based on application/@type
attribute?
i want make
packagearg
required whenapplication/@type
"batch"version
required whenapplication/@type
"service"project
required whenapplication/@type
web" or "service"
xml file
<applications> <application name="configmanagement" type="web"> <projectdirname>configmanagement</projectdirname> <project>web.configmanagement.csproj</project> <outputdirname>configmanagement</outputdirname> </application> <application name="util" type="web"> <projectdirname>web</projectdirname> <project>web.csproj</project> <outputdirname>util</outputdirname> </application> <application name="configservice" type="service"> <projectdirname>webservices\configservice</projectdirname> <project>configservice.csproj</project> <version>2015\04</version> <outputdirname>configservice</outputdirname> </application> <application name="deliveremail" type="batch"> <projectdirname>\batch\deliveremail</projectdirname> <packagearg>release</packagearg> <outputdirname>tidal\deliveremail</outputdirname> </application> </applications>
xsd file
<xs:element name="applications" maxoccurs="1"> <xs:complextype> <xs:sequence> <xs:element name="application" maxoccurs="unbounded" minoccurs="1"> <xs:complextype> <xs:all> <xs:element type="xs:string" name="projectdirname"/> <xs:element type="xs:string" name="project" minoccurs="0"/> <xs:element type="xs:string" name="version" minoccurs="0"/> <xs:element type="xs:string" name="packagearg" minoccurs="0"/> <xs:element type="xs:string" name="outputdirname"/> </xs:all> <xs:attribute type="xs:string" name="name" use="optional"/> <xs:attribute name="type" use="required"> <xs:simpletype> <xs:restriction base="xs:string"> <xs:enumeration value="web"/> <xs:enumeration value="batch"/> <xs:enumeration value="service"/> </xs:restriction> </xs:simpletype> </xs:attribute> </xs:complextype> </xs:element> </xs:sequence> </xs:complextype> </xs:element>
update: op has edited question remove use of xs:assert
, has stated in comments validation must take place in c#. answer op's question becomes:
you cannot enforce constraint varies requiredness of element based on attribute value using xsd 1.0, , microsoft not support xsd 1.1, therefore must either relax constraints or check them outside of xsd.
original xsd 1.1 answer
(retained benefit of future readers)
you're close, assertion,
<xs:assert test="count(./packagearg[@type eq 'batch']) eq 1"/>
tests @type
on packagearg
when should test @type
on application
.
the following xsd validate xml , enforce attribute-dependent requirements:
xsd 1.1
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/xmlschema" xmlns:vc="http://www.w3.org/2007/xmlschema-versioning" vc:minversion="1.1"> <xs:element name="applications"> <xs:complextype> <xs:sequence> <xs:element name="application" maxoccurs="unbounded" minoccurs="1"> <xs:complextype> <xs:all> <xs:element type="xs:string" name="projectdirname"/> <xs:element type="xs:string" name="project" minoccurs="0"/> <xs:element type="xs:string" name="version" minoccurs="0"/> <xs:element type="xs:string" name="packagearg" minoccurs="0"/> <xs:element type="xs:string" name="outputdirname"/> </xs:all> <xs:attribute type="xs:string" name="name" use="optional"/> <xs:attribute name="type" use="required"> <xs:simpletype> <xs:restriction base="xs:string"> <xs:enumeration value="web"/> <xs:enumeration value="batch"/> <xs:enumeration value="service"/> </xs:restriction> </xs:simpletype> </xs:attribute> <xs:assert test="packagearg or @type != 'batch'"/> <xs:assert test="version or @type != 'service'"/> <xs:assert test="project or not(@type = 'web' or @type = 'service')"/> </xs:complextype> </xs:element> </xs:sequence> </xs:complextype> </xs:element> </xs:schema>
be aware microsoft not support xsd 1.1. (you've tagged question 'msxml').
Comments
Post a Comment