this topic is related to xsd: define an element that can be repeated an even number of times. i would like to create a new complex type using complexContent with extension. i tried this:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:complexType name="evenOccurrence">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="B" maxOccurs="2" minOccurs="2"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="oddOcurrence">
<xs:complexContent>
<xs:extension base="evenOccurrence">
<xs:sequence>
<xs:element name="B"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
this code generate the following error: cos-nonambig: B and B (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.. how i can fix the problem
This are two similar ways of doing it:
1- Without extension:
<xs:complexType name="oddOcurrence">
<xs:sequence>
<xs:element name="B" /> <!-- 1 time -->
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<!-- 2n times -->
<xs:element name="B" maxOccurs="2" minOccurs="2" />
</xs:sequence>
</xs:sequence>
</xs:complexType>
2- Similar, with extension
<xs:complexType name="elementOneTime">
<xs:sequence>
<!-- 1 time -->
<xs:element name="B" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="oddOcurrence">
<xs:complexContent>
<xs:extension base="elementOneTime">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<!-- 2n times -->
<xs:element name="B" maxOccurs="2" minOccurs="2" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
EDIT: ¿Why was it ambiguous?
As evenOccurrence can be empty, when the parser finds the first B element of and oddOccurance, it doesn't know if its parsing the first B of an evenOccurance or the B element that only appears once.
By putting first the element that can only appear once you remove the ambiguity, as the first B element would be analyzed and then the parser would enter in a state in which it would analyze the oddOccurence type (all the other B elements).
Related
I want to do the validations like:
<A>
<B> or <C>
<D>
</A>
In the , the first element should be one of the B and C. The second element is D. And at the same time, the first element B or C and the second element do not in sequence. It could become and . Anybody know how to do it?
To match your example, please try:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="A">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element name="B" type="xs:string"/>
<xs:element name="C" type="xs:string"/>
</xs:choice>
<xs:element name="D" type="xs:string" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
You have to use two things here, the first one is <xs:choice> which allows only one elements to be present in xml.
In order to make an element optional (D) you have to specify minOccurs="0".
Edited (after feedback): All valid cases are covered with this XSD.
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="B" type="xs:string"/>
<xs:element name="C" type="xs:string"/>
<xs:element name="D" type="xs:string"/>
<xs:complexType name="OurType">
<xs:choice>
<xs:sequence>
<xs:element ref="D"/>
<xs:choice>
<xs:element ref="B"/>
<xs:element ref="C"/>
</xs:choice>
</xs:sequence>
<xs:sequence>
<xs:choice>
<xs:element ref="B"/>
<xs:element ref="C"/>
</xs:choice>
<xs:element ref="D"/>
</xs:sequence>
</xs:choice>
</xs:complexType>
<xs:element name="A" type="OurType"/>
</xs:schema>
I get the best practice. It should be as below:
<xs:element name="A">
<xs:complexType>
<xs:all>
<xs:element ref="Choice" minOccurs="1" maxOccurs="1"/>
<xs:element ref="D" minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="D" type="xs:string"/>
<xs:element name="Choice" abstract="true"/>
<xs:element name="B" substitutionGroup="Choice">
</xs:element>
<xs:element name="C" substitutionGroup="Choice">
</xs:element>
Hi again SO community,
got another request regarding how to define an XSD schema correctly.
Given I have an XML file like:
<?xml version="1.0" encoding="UTF-8" ?>
<transformation xmlns="http://www.denktmit.de/pdi/ktr" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.w3.org/2001/XMLSchema-instance
./test.xsd">
<info>
<name>TrafoName</name>
<description>TrafoDescription</description>
</info>
<changedby>LastUser</changedby>
<step>
<type>FileInput</type>
<description>FileInput Step description</description>
<FileInputParameterOne>FileInputParam</FileInputParameterOne>
<another>1</another>
</step>
<step>
<type>Select</type>
<description>Select Step description</description>
<SelectParameterOne>SelectParameterOne</SelectParameterOne>
<SelectParameterTwo>SelectParameterTwo</SelectParameterTwo>
<another>2</another>
</step>
</transformation>
This resembles the style of the transformation files as produced by http://community.pentaho.com/projects/data-integration/
As you can see, each step contains several sequence nodes on top
<type>Select</type>
<description>Select Step description</description>
and on bottom:
<another>2</another>
In between, arbitrary complex xml subtrees may occur. But what exactely max occur is determined by the value in "type". The use case is to store specific configurations for concrete Java classes, that all implement an interface, defining getters/setter for "type", "description" and "another" and defining addtional object structure themself. It would also be sufficient to neglect the order, as long as all the elements, needed for a specific class are somehow present.
I already read:
How to group types & subtypes in XSD
xsd: How to extend a type with an unordered list of elements
Use <xs:all> in XML schema's complexType?
xsd: How to extend a type with an unordered list of elements
And I tried something like
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.denktmit.de/pdi/ktr" elementFormDefault="qualified"
attributeFormDefault="unqualified" xmlns="http://www.denktmit.de/pdi/ktr">
<xs:element name="transformation">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="step" type="fileInputStep"></xs:element>
<xs:element name="step" type="selectStep"></xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="stepComplexType" abstract="true"></xs:complexType>
<xs:complexType name="fileInputStep">
<xs:complexContent>
<xs:extension base="stepComplexType">
<xs:sequence>
<xs:element name="type" minOccurs="1"
maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string"></xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="description" type="xs:string"
minOccurs="1" maxOccurs="1"></xs:element>
<xs:element name="FileInputParameterOne" type="xs:string">
</xs:element>
<xs:element name="another" type="xs:int" minOccurs="1"
maxOccurs="1"></xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="selectStep">
<xs:complexContent>
<xs:extension base="stepComplexType">
<xs:sequence>
<xs:element name="type" minOccurs="1"
maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="Select"></xs:pattern>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="description" type="xs:string"
minOccurs="1" maxOccurs="1"></xs:element>
<xs:element minOccurs="1" name="SelectParameterOne"
type="xs:string">
</xs:element>
<xs:element minOccurs="1" name="SelectParameterTwo"
type="xs:string">
</xs:element>
<xs:element name="another" type="xs:int" minOccurs="1"
maxOccurs="1"></xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
But it is not working, telling me:
Multiple annotations found at this line: validation against this
schema, ambiguity would be created for those two particles.
- Start tag of element
- cos-element-consistent: Error for type '#AnonType_transformation'. Multiple elements with name 'step', with different types, appear in
the model group.
Any ideas?
You may use xsd Group. Here's an sample for your reference
XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="transformation">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="step" type="stepType"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="stepComplexType" abstract="true"></xs:complexType>
<xs:group name="selectParamGroup">
<xs:sequence>
<xs:element name="SelectParameterOne" type="xs:string" minOccurs="1" maxOccurs="1">
</xs:element>
<xs:element name="SelectParameterTwo" type="xs:string" minOccurs="1" maxOccurs="1">
</xs:element>
</xs:sequence>
</xs:group>
<xs:group name="paramGroup">
<xs:choice>
<xs:element name="FileInputParameterOne" type="xs:string">
</xs:element>
<xs:group ref="selectParamGroup">
</xs:group>
</xs:choice>
</xs:group>
<xs:complexType name="stepType">
<xs:complexContent>
<xs:extension base="stepComplexType">
<xs:sequence>
<xs:element name="type" minOccurs="1"
maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string"></xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="description" type="xs:string"
minOccurs="1" maxOccurs="1"></xs:element>
<xs:group ref="paramGroup"></xs:group>
<xs:element name="another" type="xs:int" minOccurs="1"
maxOccurs="1"></xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
XML:
<?xml version="1.0" encoding="UTF-8" ?>
<transformation>
<step>
<type>FileInput</type>
<description>FileInput Step description</description>
<FileInputParameterOne>FileInputParam</FileInputParameterOne>
<another>1</another>
</step>
<step>
<type>Select</type>
<description>Select Step description</description>
<SelectParameterOne>SelectParameterOne</SelectParameterOne>
<SelectParameterTwo>SelectParameterTwo</SelectParameterTwo>
<another>2</another>
</step>
</transformation>
I have some complexType element which is parent of some element:
<xs:complexType name="elementParent">
<xs:sequence>
<xs:element name="b" type="xs:String" />
<xs:element name="c" type="xs:String" />
</xs:complexType>
now I want to create anothex complex type which will be extension of my parent. Problem is in order. First element should be a then b and then c. I just know this option where order will be b c a which I dont want:
<xs:complexType name="elementChild">
<xs:complexContent>
<xs:extension base="elementParent">
<xs:sequence>
<xs:element name="a" type="xs:String" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:extension> creates a type which is a sequence containing first the base type and then the explicit content defined in <xs:extension>. If you only want to add new elements preceding the elements of another type, you could define the common elements as an <xs:group> and then refer to that group in both of the type definitions.
Something like this:
<!-- common elements defined as a group -->
<xs:group name="elementGroup">
<xs:sequence>
<xs:element name="b" type="xs:string" />
<xs:element name="c" type="xs:string" />
</xs:sequence>
</xs:group>
<!-- group is referred to in element type definitions -->
<xs:element name="elementParent">
<xs:complexType>
<xs:sequence>
<xs:group ref="elementGroup" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="elementChild">
<xs:complexType>
<xs:sequence>
<xs:element name="a" type="xs:string" />
<xs:group ref="elementGroup" />
</xs:sequence>
</xs:complexType>
</xs:element>
I have a schema, where there are 3 elements and these 3 elements still have more sub elements. Lets name 1st element as Header, 2nd one as record, 2rd one as footer.
There is one occurence of header, multiple occurences of record and one occurence of footer again.
so the input to schema looks like
header
record..
record..
...
..
footer
now my problem is . my schema is defined like this
<xs:element minOccurs="1" maxOccurs="1" name="HEADER">
<xs:element minOccurs="1" maxOccurs="unbounded" name="Record">
<xs:element minOccurs="1" maxOccurs="1" name="FOOTER">
when a file (with a header 2 records and footer)is parsed through this schema. the parser recognizes recognizes the header and both the records and gives an exception after recognizing the 2nd record and doesn't give the footer. How do we define max and min occurs when there are 2 or more elements and middle element has unbounded as max occurs
EDIT:
thanks for the replies. This is my xsd file.
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:NS="sample.xsd" xmlns="sample.xsd" elementFormDefault="qualified" targetNamespace="sample.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="PTRO">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="HEADER">
<xs:complexType>
<xs:sequence>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="header_sub_element">
<xs:simpleType>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="1" maxOccurs="unbounded" name="Record">
<xs:complexType>
<xs:sequence>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="Record_sub_element">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="11" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="1" maxOccurs="1" name="FOOTER">
<xs:complexType>
<xs:sequence>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="footer_sub_element">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="9" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
# marc_s the problem is when an input file (.txt file) which contains a header, 2 records, footer is parsed using this schema, the parser recognizes header and records...and after this it gives an exception since it doesn't recognize the footer. The max occurs of Record is unbounded. Does this have something to do with the exception ??
You have to use < sequence >< /sequence > instead of the < all >< /all > or < choice >< /choice >.
That should solve the problem.
I want to specify that either fieldname or freetext must always be present in XML files that apply to this XSD. Is there a way to do that?
<xs:complexType name="tSome">
<xs:sequence>
<!-- either one of the two below has to be present. -->
<xs:element name="fieldname" type="xs:string" />
<xs:element name="freetext" type="xs:string" />
<!-- this one below must always be present -->
<xs:element name="dbtablename" type="xs:string" />
</xs:sequence>
</xs:complexType>
There is a Choice Indicator in XML Schema, which allows you to take one of the contained elements, but not two or more. If you want any 2 of 3, I suggest doing something like this:
<xs:choice>
<xs:element name="fieldname" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="freetext" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="dbtablename" type="xs:string" minOccurs="0" maxOccurs="1" />
</xs:choice>
<xs:choice>
<xs:element name="fieldname" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="freetext" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="dbtablename" type="xs:string" minOccurs="0" maxOccurs="1" />
</xs:choice>
(Maybe maxOccurs will prevent you from choosing one and the same element twice.)
If that does not work, nothing will I think.
Edited: I didn't correctly understand the question the first time. If you want dbtablename to always be present with any one of fieldname or freetext, then this is the answer:
<xs:complexType name="tSome">
<xs:sequence>
<xs:choice>
<xs:element name="fieldname" type="xs:string" />
<xs:element name="freetext" type="xs:string" />
</xs:choice>
<xs:element name="dbtablename" type="xs:string" />
</xs:sequence>
</xs:complexType>
So, you want either fieldname or freetext and not both? or maybe both? and then dbtablename optionally?
Here is 1 or 2 of the elements:
<xs:choice minOccurs="1" maxOccurs="2">
<xs:element name="fieldname" type="xs:string"/>
<xs:element name="freetext" type="xs:string"/>
<xs:element name="dbtablename" type="xs:string"/>
</xs:choice>
Is this what you want? or did you want dbtablename to be separate?