Is It Impossible to have elements with same name in xsd? - xsd

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

Related

xsd restriction in extended element

Suppose I have an element A and an element B extended from A as shown below.
<xsd:complexType name="A">
<xsd:sequence>
<xs:element name="desiredVariable" type="xs:string"/>
</xsd:sequence>
<xsd:complexType>
<xsd:complexType name="B">
<xsd:complexContent>
<xsd:extension base="A">
<xsd:sequence>
<xs:element name="anotherVariable" type="xs:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
I have an usecase where desiredVariable in A can take any value and the same desiredVariable in B should be a fixed value. ie I have to apply restiction on desiredValue in B. How can I do that?
In general, XML 1.0 does not allow conditional data. But you can acheive what you want through extensions. This is how to implement it in XML 1.0:
You'll need to define the base element as abstract if you want to enforce the limitations. In the XML file they will need to specify the extension they are implementing. You need to define your restrictions separately.
XSD:
<xsd:complexType name="A" abstract="true">
<xsd:sequence>
<xs:element name="desiredVariable" type="xs:string"/>
</xsd:sequence>
<xsd:complexType>
<xsd:complexType name="B">
<xsd:complexContent>
<xsd:extension base="A">
<xsd:restriction base="checksumType">
<xsd:sequence>
<xs:element name="desiredVariable" type="xs:string" fixed="FixedValue"/>
<xs:element name="anotherVariable" type="xs:stringLimitedType"/>
</xsd:sequence>
</xsd:restriction>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:simpleType name="stringLimitedType">
<xsd:restriction base="xs:string">
<xsd:pattern value="([a-zA-Z0-9])*"/>
</xsd:restriction>
</xsd:simpleType>
XML:
<A namespace:type="B">
...
</A>
See the following for more on abstraction and extensions:
XSD schema abstract type problem
I have heard there are more options when using XML 1.1.

XSD extend restricted type

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?

Replacing old XSD with new

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.

XSD choice inside all

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>

How to validate textfield element in xsd:schema

I am using xsd:schema which will be used to generated desired xml, I have a title field in xsd:schema.
I want to validate it from xsd:schema only that whenever user try to put values more than 10 characters, it will generate the error.
Below is the part of my xsd:schema
<xsd:sequence>
<xsd:element name="Title" minOccurs="0" maxOccurs="1" type="xsd:normalizedString"/>
<xsd:element name="City" minOccurs="0" maxOccurs="1" type="tcmi:SimpleLink">
<xsd:annotation>
<xsd:appinfo>
<tcm:linktype>ComponentLink</tcm:linktype>
<tcm:AllowMultimediaLinks>false</tcm:AllowMultimediaLinks>
<tcm:AllowedTargetSchemas>
<tcm:TargetSchema xlink:href="tcm:227-190428-8" xlink:title="City"/>
</tcm:AllowedTargetSchemas>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="FlightLinkText" minOccurs="0" maxOccurs="1" type="xsd:normalizedString"/>
</xsd:sequence>
I means that can we validate it from <xsd:element name="Title" minOccurs="0" maxOccurs="1" type="xsd:normalizedString"/>
Please suggest!
Have you tried something like:
<xsd:element name="Title" minOccurs="0" maxOccurs="1">
<xsd:simpleType>
<xsd:restriction base="xsd:normalizedString">
<xsd:maxLength value="10"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>

Resources