Choice between two elements with same name - xsd

I am struggling with a choice between an element that is mixed and one that is not.
<xs:group name="code">
<xs:choice>
<xs:element name="code" type="multiLineCode"/>
<xs:element name="code" type="code"/>
</xs:choice>
</xs:group>
<xs:complexType name="code" mixed="true">
<xs:group ref="htmlInlineElements" minOccurs="0" maxOccurs="unbounded"/>
</xs:complexType>
<xs:complexType name="multiLineCode">
<xs:sequence>
<xs:element name="line" maxOccurs="unbounded">
<xs:complexType mixed="true">
<xs:group ref="htmlInlineElements" minOccurs="0" maxOccurs="unbounded"/>
<xs:attribute name="indentation" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
Why do I want to do this crazy move?
The background is that mixed text in the <code> element is reformatted by the IDE so far. Since the content later moves to an HTML <pre> element there are display problems here.
existing <code> example:
<code>
if (<function>ParseInt</function>("42") === 42)
<function>doSomething</function>();
</code>
<code> example for multiline:
<code>
<line indentation="0">if (<function>ParseInt</function>("42") === 42)</line>
<line indentation="1"><function>doSomething</function>();</line>
</code>
So i want either a <code> element that's not multiline but has <line> elements or a multiline code element. As there are 670 code examples out i cannot change them all.
Do you have a solution for my choice-problem? And in general: Am i on the right way solving this problem?
Thank you very much!

Related

I need one element in xs:all to repeat twice

<xs:complexType>
<xs:all>
<xs:element name="AN" minOccurs="0"/>
<xs:element name="ME" minOccurs="0"/>
<xs:element name="preview" minOccurs="0"/>
<xs:element name="NZ" minOccurs="0"/>
<xs:element name="RE" minOccurs="0"/>
<xs:element name="RU" minOccurs="0"/>
<xs:element name="AU" minOccurs="0"/>
<xs:element name="SE" minOccurs="0"/>
<xs:element name="CM" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
In the above code, i want the element "ME" to be used twice in XML and other elements should be used exactly once but in anyorder.
What you want to do is the following. However while this is fine under XSD 1.1, its not under XSD 1.0.
<xs:element name="MyElm">
<xs:complexType>
<xs:all>
<xs:element name="AN" />
<xs:element name="ME" minOccurs="2" maxOccurs="2" />
<xs:element name="preview" />
<xs:element name="NZ" />
<xs:element name="RE" />
<xs:element name="RU" />
<xs:element name="AU" />
<xs:element name="SE" />
<xs:element name="CM" />
</xs:all>
</xs:complexType>
</xs:element>
In XSD 1.0, I'm pretty sure this is not possible. If you can live without them being 'in any order' then you can use a xs:sequence, and if you can live with 0-1 and 0-2 items then you could use a xs:choice. But that's as close as you can get.

XML Schema with a combination of choice and all

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>

extending existing complexType

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).

How to fully define an XML Schema for same element name but differing subtype

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>

How to use extension in xsd when order of element is important

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>

Resources