My XML looks like . I have two elements with same name. But I am not being able to get those elements in XSD.
Here Book is the element that appears twice but has different attributes. All attributes in their respective Book elements are required.
The error says
Element Books is not consistent with element Books
XML :
<TestRoot>
<Test Shelf="1">
<Value>
<Book Name="Wolves" />
</Value>
</Test>
<Test Shelf="2">
<Value>
<Book Name="Dogs" Pages="500" Photos="50" />
</Value>
</Test>
</TestRoot>
My XSD looks like :
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema....>
<xsd:element name="TestRoot">
<xsd:complexType>
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element name="Test" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:choice>
<xsd:element name="Value">
<xsd:complexType>
<xsd:choice minOccurs="1" maxOccurs="1">
<xsd:element name="Book">
<xsd:complexType>
<xsd:attribute name="Name" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="40"/>
<xsd:enumeration value="Wolves"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="Book">
<xsd:complexType>
<xsd:attribute name="Book" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="40"/>
<xsd:enumeration value="Dogs"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="Pages" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="Photos" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="24"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:choice>
<xsd:attribute name="Shelf" use="optional">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="100"/>
<xsd:enumeration value="1"/>
<xsd:enumeration value="2"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Not sure where I am wrong ? Any help?
Try something like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="TestRoot" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="TestRoot" msdata:IsDataSet="true" msdata:Locale="en-US">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Test">
<xs:complexType>
<xs:sequence>
<xs:element name="Value" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<!-- the <Book> node is just of "BookType" type -->
<xs:element name="Book" type="BookType" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Shelf" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
<!-- define the "BookType" which represents a single <Book> node -->
<xs:complexType name="BookType">
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="Pages" type="xs:string" />
<xs:attribute name="Photos" type="xs:string" />
</xs:complexType>
</xs:schema>
This XSD defines a new complex type BookType which is used to define how the <Book> nodes inside <Value> look like.
In general, I would also define a complex type for any of the XML nodes you have - I'd create a ValueType to handle how a <Value> node is made up, and I'd create a TestType for <Test> and a TestRootType for the <TestRoot> as well.
Having those really deeply nested XSD structures makes it really hard to "grasp" what's going on - defining a type for each node and then assigning them to the nodes makes it much more readable and understandable, in my opinion
Can you have an allready restricted type and then derive from this type by extension and add elements that do not fit to a base type?
<xsd:complexType name="absHcontainerType">
<xsd:complexContent>
<xsd:restriction base="e:urContentType">
<xsd:sequence>
<xsd:element ref="e:absMcontainer" minOccurs="0"
maxOccurs="1" />
<xsd:element ref="e:absHtitle" minOccurs="1" maxOccurs="unbounded" />
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element ref="e:absMcontainer" />
<xsd:element ref="e:absHcontainer" />
<xsd:element ref="e:absContainer" />
</xsd:choice>
</xsd:sequence>
<xsd:attributeGroup ref="e:typehcontainer" />
<xsd:attributeGroup ref="e:anyattr" />
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
And then derive this like this:
<xsd:complexType name="absHcontainerType2">
<xsd:complexContent>
<xsd:extension base="absHcontainerType">
<xs:sequence>
<xs:element name="xy" type="xs:string"/>
<xs:element name="xyz" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xsd:complexContent>
</xsd:complexType>
As long as you don't put back things that got restricted away, I wouldn't expect a problem. Are you in fact getting an error when you try it?
I have been tasked to replace the xsd for a particular solution. However, I keep getting an "element is not supported in this context."
Here is the original xsd:
public const string Xsd = #"
<xs:schema attributeFormDefault='unqualified' elementFormDefault='qualified' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
<xs:element name='DataRow'>
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs='unbounded' name='Data'>
<xs:complexType>
<xs:attribute name='Site' type='xs:string' use='required' />
<xs:attribute name='Month_Num' type='xs:unsignedShort' use='required' />
<xs:attribute name='Numerator' type='xs:unsignedByte' use='required' />
<xs:attribute name='Data_Indicator' type='xs:string' use='required' />
<xs:attribute name='Budgeted' type='xs:unsignedByte' use='required' />
<xs:attribute name='Executive_Comments' type='xs:string' use='required' />
<xs:attribute name='Fleet_Executive_Comments' type='xs:string' use='required' />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>";
Here is what I am supposed to be replacing it with:
<xs:schema attributeFormDefault='unqualified' elementFormDefault='qualified' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
<MonthlyValues>
<MonthlyValue IndicatorName='name' LocationName='name' GroupingName='name' Year='MonthNum.Value.Year' Month='MonthNum.Value.Month' Numerator='Numerator' Budget='Budget'>
</MonthlyValue>
</MonthlyValues>
</xs:schema>
The schema was made by someone else and I was supposed to just be able to replace it. Unfortunately its not working out that way and I know very little about it.
should I change
<MonthlyValues>
to
<xs:element name='MonthlyValues> and keep the
<xs:sequence>
<xs:element maxOccurs='unbounded' name='MonthlyValues'>
<xs:complexType>
and add the
<MonthlyValue IndicatorName='name' LocationName='name' GroupingName='name' Year='MonthNum.Value.Year' Month='MonthNum.Value.Month' Numerator='Numerator' Budget='Budget'>
</MonthlyValue>
afterward? Actually, I tried that and it didn't work, but is there something similar I have to do?
XSD is something else... you do seem to be new to XSD so maybe the quickest way to get you started is to generate an XSD from your sample XML. Tweak the generated to match the XMLs. Use the XSD below as a starting point.
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="MonthlyValues">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="MonthlyValue">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="IndicatorName" type="xsd:string" use="required" />
<xsd:attribute name="LocationName" type="xsd:string" use="required" />
<xsd:attribute name="GroupingName" type="xsd:string" use="required" />
<xsd:attribute name="Year" type="xsd:string" use="required" />
<xsd:attribute name="Month" type="xsd:string" use="required" />
<xsd:attribute name="Numerator" type="xsd:string" use="required" />
<xsd:attribute name="Budget" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
You should rely on an editor to help you through the learning... Eclipse, Netbeans, etc. come with decent editors, and free.
You can't put choice tag inside the all tag. So, is there any workaround to get this functionallity?
For example, I have<settings> tag like:
<settings>
<logging />
<sending />
<useonly />
</settings>
Or something like
<settings>
<logging />
<notuseonly />
<sending />
</settings>
So I want to prevent <useonly> and <notuseonly> showing up together, while the order is not important. And if allowed, in XSD it would look like:
<xs:all>
<xs:element minOccurs="0" maxOccurs="1" ref="sending" />
<xs:element minOccurs="0" maxOccurs="1" ref="logging" />
<xs:choice>
<xs:element minOccurs="0" maxOccurs="1" ref ="useonly" />
<xs:element minOccurs="0" maxOccurs="1" ref ="notuseonly" />
</xs:choice>
</xs:all>
Any thoughts?
Check this link: http://www.w3.org/wiki/Needs_choice_inside_all
I summarize for you the solutions proposed:
One solution is to wrap the element that can change inside another:
<xsd:all>
<xsd:element minOccurs="0" maxOccurs="1" ref="sending" />
<xsd:element minOccurs="0" maxOccurs="1" ref="logging"/>
<xsd:element minOccurs="0" maxOccurs="1" ref ="usetype"/>
</xsd:all>
<xsd:element name="usetype">
<xsd:complexType>
<xsd:choice>
<xsd:element ref="useonly"/>
<xsd:element ref="notuseonly"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
The other one is to use a substitution group:
<xsd:all>
<xsd:element ref="sending"/>
<xsd:element ref="logging"/>
<xsd:element ref="usetype"/>
</xsd:all>
</xsd:complexType>
<xsd:element name="usetype" abstract="true"/>
<xsd:element name="useonly" substitutionGroup="usetype"> ... </xsd:element>
<xsd:element name="notuseonly" substitutionGroup="usetype"> ... </xsd:element>
I have a choice complexType named abType:
<xs:complexType name="abType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="a"/>
<xs:element name="b"/>
</xs:choice>
</xs:complexType>
This type can be used to create elements with a and b nodes in any order like this for example:
<ab>
<b/>
<a/>
</ab>
Now I want to create a derived type called abcType to allow the nodes a, b and c in any order. Therefore I created a new complexType based on abType:
<xs:complexType name="abcType">
<xs:complexContent>
<xs:extension base="abType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="c"/>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>
After that I created a abc node:
<abc>
<c/>
<b/>
<a/>
</abc>
But this node is invalid! It is not valid to put any a or b after a c. The reason is, that deriving a type from a base type creates an implicite sequence although both types are choices. XMLspy illustrates it in this way:
This result is quite useless for choice types.
So my question is: How to extend a choice type without sequencing the choice?
Here is the complete XSD and an XML test file to reproduce the problem:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="ab"/>
<xs:element ref="abc"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ab" type="abType"/>
<xs:complexType name="abType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="a"/>
<xs:element name="b"/>
</xs:choice>
</xs:complexType>
<xs:element name="abc" type="abcType"/>
<xs:complexType name="abcType">
<xs:complexContent>
<xs:extension base="abType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="c"/>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
Example:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="inherit-choice.xsd">
<ab>
<b/>
<a/>
</ab>
<abc>
<c/>
<b/>
<a/>
</abc>
</root>
There is a way to do this that relies on the fact that a choice within a choice acts as a bigger choice.
First, define an element group which contains a single choice from all the elements within the base element:
<xs:group name="common_ab_elements">
<xs:choice>
<xs:element name="a"/>
<xs:element name="b"/>
</xs:choice>
</xs:group>
Then you can use this in your definition of abElement in place of the elements you had before:
<xs:complexType name="abType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:group ref="common_ab_elements"/>
</xs:choice>
</xs:complexType>
If you need an extended type, then you can extend the choice:
<xs:complexType name="abcType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:group ref="common_ab_elements"/>
<xs:element name="c"/>
</xs:choice>
</xs:complexType>
This is equivalent to:
<xs:complexType name="abcType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:choice>
<xs:element name="a"/>
<xs:element name="b"/>
</xs:choice>
<xs:element name="c"/>
</xs:choice>
</xs:complexType>
And because of the nature of the choice operation, this is in turn equivalent to:
<xs:complexType name="abcType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="a"/>
<xs:element name="b"/>
<xs:element name="c"/>
</xs:choice>
</xs:complexType>
...which is what you want.
If you have attributes as well, then you may also need to define a common base class which you can extend. With this scheme, only classes with no derived classes should have elements, as it's the presence of elements on the base elements that forces the sequencing.
What we are effectively doing here is defining the inheritance of choice elements separately from the elements hierarchy itself.
Unfortunately, the short answer is NO, you can't extend a choice compositor. Logically, if there is some sort of relationship between a, b, and c (as in Java, .NET, everything is ultimately an Object, you could do the same in XSD) then I suggest the use of substitution groups instead (or, if you prefer, something based on xsi:type).
UPDATE with an example. The XSD-1:
<?xml version="1.0" encoding="utf-8" ?>
<!--W3C Schema generated by QTAssistant/W3C Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="ab" type="abType"/>
<xsd:complexType name="abType">
<xsd:sequence>
<xsd:element ref="ExtensibleChoice-A" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="ExtensibleChoice-A" type="ExtensibleChoiceBaseType" abstract="true" />
<xsd:complexType name="ExtensibleChoiceBaseType" abstract="true">
<xsd:sequence/>
</xsd:complexType>
<xsd:element name="a" substitutionGroup="ExtensibleChoice-A" type="aType" block="#all"/>
<xsd:element name="b" substitutionGroup="ExtensibleChoice-A" type="bType" block="#all"/>
<xsd:element name="c" substitutionGroup="ExtensibleChoice-A" type="cType" block="#all"/>
<xsd:complexType name="aType">
<xsd:complexContent>
<xsd:extension base="ExtensibleChoiceBaseType">
<xsd:sequence>
<xsd:element name="aChild" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="bType">
<xsd:complexContent>
<xsd:extension base="ExtensibleChoiceBaseType">
<xsd:sequence>
<xsd:element name="bChild" type="xsd:int"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="cType">
<xsd:complexContent>
<xsd:extension base="ExtensibleChoiceBaseType">
<xsd:sequence>
<xsd:element name="cChild" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
The extensibility is that at a point in time, you may have only a, b and c as members. If you, or a consumer, decide to add something (say a d element), then you simply create another schema that references the old one, with the new element d, and then use that new schema instead. The old XSD file doesn't get touched; generating new JAXB classes (as an example) will result in backward compatible code.
So, XSD-1 will validate something like this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<ab xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
<a>
<aChild>aChild1</aChild>
</a>
<b>
<bChild>1</bChild>
</b>
<c>
<cChild>cChild1</cChild>
</c>
</ab>
You would need something like this (XSD-2):
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema1.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema1.xsd" xmlns:b="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://tempuri.org/XMLSchema.xsd" schemaLocation="XSD-1.xsd"/>
<xsd:element name="d" substitutionGroup="b:ExtensibleChoice-A" type="dType" block="#all"/>
<xsd:complexType name="dType">
<xsd:complexContent>
<xsd:extension base="b:ExtensibleChoiceBaseType">
<xsd:sequence>
<xsd:element name="dChild" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
the diagram shows the "new" list of members, d is highlighted in blue:
To validate this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<ab xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:d="http://tempuri.org/XMLSchema1.xsd">
<a>
<aChild>aChild1</aChild>
</a>
<d:d>
<d:dChild>1</d:dChild>
</d:d>
</ab>
Another example with Substitutions.
XSD
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="abExtension"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="abExtension" type="abExtensionType"/>
<xs:complexType name="abExtensionType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="a"/>
<xs:element name="b"/>
</xs:choice>
</xs:complexType>
<xs:element name="abcExtension" substitutionGroup="abExtension">
<xs:complexType>
<xs:complexContent>
<xs:extension base="abExtensionType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="c"/>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="abcdExtension" substitutionGroup="abExtension">
<xs:complexType>
<xs:complexContent>
<xs:extension base="abExtensionType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="c"/>
<xs:element name="d"/>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:schema>
Sample XML's that validate with this are
abcExtension.xml
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Test.xsd">
<abcExtension>
<b></b>
<a></a>
<c></c>
</abcExtension>
</root>
abcdExtension.xml
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Test.xsd">
<abcdExtension>
<a>text</a>
<b>test</b>
<d>text</d>
<c>text</c>
</abcdExtension>
</root>
abExtension.xml
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Test.xsd">
<abExtension>
<b></b>
<a></a>
</abExtension>
</root>
If your focus is on extending rather than type inheritance, a <choice> can be extended by redefining a <group> as follows:
File "abc.xsd" containing the base schema:
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="any"
xmlns:n="any"
elementFormDefault="qualified">
<group name="baseGroup">
<choice>
<element name="a"/>
<element name="b"/>
<element name="c"/>
</choice>
</group>
<complexType name="choiceType">
<sequence minOccurs="0" maxOccurs="unbounded">
<group ref="n:baseGroup"/>
</sequence>
</complexType>
<element name="test">
<complexType>
<sequence>
<element name="sample" type="n:choiceType" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
</schema>
File "abcdef.xsd" extending the <choice> defined in the base schema:
<?xml version="1.0"?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="any"
xmlns:n="any"
elementFormDefault="qualified">
<redefine schemaLocation="abc.xsd">
<group name="baseGroup">
<choice>
<group ref="n:baseGroup"/>
<element name="d"/>
<element name="e"/>
</choice>
</group>
</redefine>
</schema>
This validates the following xml file, for instance:
<?xml version="1.0" encoding="UTF-8"?>
<test
xmlns="any"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="any ../schemas/abcde.xsd">
<sample>
<a/>
<c/>
<b/>
<a/>
</sample>
<sample>
<c/>
</sample>
<sample>
</sample>
<sample>
<a/>
<e/>
<b/>
<d/>
<a/>
</sample>
</test>
Its Very Simple you can do using "choice" keyword and set its occurrence
<xs:element name="Product">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="1" maxOccurs="14">
<xs:element>
</xs:element>
// Post your element configuration here
</xs:choice>
</xs:sequence>
</xs:complexType>