XSD - Restricting attribute values to another element attribute value - xsd

I have the following XML:
<Content name="contentName1">
<!-- Some sub elements here -->
</Content>
<Sequence Name="sequenceName1">
<Content name="contentName1" />
<!-- Some sub elements here -->
</Sequence>
with the following XSD
<xs:element maxOccurs="unbounded" name="Content">
<xs:complexType>
<xs:attribute name="Name" type="xs:string" use="required" />
<!-- other definitions here -->
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" name="Sequence">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Content">
<xs:complexType>
<xs:attribute name="ContentName" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
In the XSD, how can I tell to the ContentName attribute of the Content elements of Sequence to only accepts value declared in the ContentName of Content elements?
e.g: with the XML provided above, only contentName1 will be accepted in the Content of sequence.

Identity constraint definitions are used for enforcing the unique, primary key and foreign key relations. you need to first define a key element for the content element and then use a keyref in the inner content element for the schema validator to enforce the condition you mentioned. Refer the below link it has some examples as well, also the tutorial in xfront for xsd covers some examples -
http://www.w3.org/TR/xmlschema11-1/#Identity-constraint_Definition_details
http://www.xfront.com/files/xml-schema.html

i am not good in xsd too, but maybe you will change <xs:attribute name="Name" type="xs:string" use="required" /> to <xs:attribute name="Name" type="contentNames" use="required" />
and create
<xs:simpleType name="contentNames" >
<xs:restriction base="xs:token">
<xs:enumeration value="contentName1"/>
<xs:enumeration value="contentName2"/>
<xs:pattern value="contentName[1234567890][1234567890]"/>
<xs:enumeration value="contentName1"/>
</xs:restriction>
</xs:simpleType>
for
<xs:pattern value="contentName[1234567890][1234567890]"/>
contentName1-99 but dont know if you can use <xs:enumeration/> too, you can try

Related

How to extend built-in types with a set of attributes?

I need to extend several xml elements of different XML Schema built-in types (e.g. xs:anyURI, xs:string...) with the same two attributes att1 and att2 over and over again.
Example xml to validate:
<extendedURI att1="abc" att2="def">my.uri</extendedURI>
I have tried defining a complex type parent:
<!-- The parent type defines the two attributes I'm interested in -->
<xs:complexType name="parentType">
<xs:attribute name="att1" type="xs:string" />
<xs:attribute name="att2" type="xs:string" />
</xs:complexType>
and then declaring the type of my elements as xs:anyURI and extending them, but this is not valid:
<!-- XXX: The following is not permitted: I cannot redefine the xs:anyURI type -->
<xs:element name="extendedURI" type="xs:anyURI">
<xs:complexType>
<xs:complexContent>
<xs:extension base="parentType" />
</xs:complexContent>
</xs:complexType>
</xs:element>
I have also tried to restrict the simpleContent to xs:anyURI and extended it with parentType, but I couldn't find how. Something like:
<xs:element name="extendedURI">
<xs:complexType>
<xs:simpleContent>
<!-- XXX: This is not permited: -->
<xs:restriction base="xs:anyURI">
</xs:restriction>
<xs:extension base="parentType">
</xs:extension>
<!-- 'xs:restriction' and 'xs:extension' are alternatives and
cannot be defined at the same time!
-->
<xs:simpleContent>
</xs:complexType>
</xs:element>
So how could I accomplish this? Is it possible to extend a built-in type with a complexType (or to restrict a complexType with the definition of a built-in type)?
It is possible to reuse the same set of attributes by using the xsd:attributeGroup:
<!-- several types will declare this set of attributes -->
<xs:attributeGroup name="extensible">
<xs:attribute name="att1" type="xs:string" />
<xs:attribute name="att2" type="xs:string" />
</xs:attributeGroup>
<!-- extending a simple content element with the two 'inherited' attributes -->
<xs:element name="extendedURI">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:anyURI">
<xs:attributeGroup ref="extensible"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>

XSD validation error in #AnonType_Apps

When I tried to validate my XSD it gives the error
S4s-elt-invalid-content.1: The Content Of '#AnonType_Apps' Is Invalid.
Element 'sequence' Is Invalid, Misplaced, Or Occurs Too Often.
don't know what should be done
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name ="Apps">
<xs:complexType>
<xs:attribute name ="List_Type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="new releases"/>
<xs:enumeration value="top rated"/>
<xs:enumeration value="category list"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name ="Server_IP" type="xs:string" fixed="10.144.50.55"/>
<xs:sequence>
<xs:element name ="App" minOccurs="1" maxOccurs="20">
<xs:complexType>
<xs:attribute name ="device_type" use="optinal" >
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="tablet"/>
<xs:enumeration value="phone"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name ="app_id" type="xs:string"/>
<xs:attribute name ="installed" type="xs:boolean" default="false"/>
<xs:sequence>
<xs:element name ="app_name" type="xs:string"></xs:element>
<xs:element name ="catogry" minOccurs="1" maxOccurs="3"></xs:element>
<xs:element name ="version" type="xs:string"></xs:element>
<xs:element name ="description" type="xs:string"></xs:element>
<xs:element name ="reviews" use="required">
<xs:complexType>
<xs:sequence>
<xs:element name ="review" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:all>
<xs:element name ="reviewer_name" type="xs:string"></xs:element>
<xs:element name ="review_date">
<xs:complexType>
<xs:restriction base="xs:string">
<xs:pattern value="\d{4}\-\d{2}\-\d{2}"/>
</xs:restriction>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name ="review_time">
<xs:complexType>
<xs:restriction base="xs:string">
<xs:pattern value="\d{2}:\d{2}:\d{}"/>
</xs:restriction>
</xs:complexType>
</xs:element>
<xs:element name ="content" type="xs:string"></xs:element>
<xs:element name ="rating">
<xs:complexType>
<xs:restriction base="xs:float">
<xs:minInclusive value="0" />
<xs:maxInclusive value="5" />
</xs:restriction>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Within a complexType element, the content model comes first and the attribute declarations come last. Move the outermost sequence element to make it the first child of the complex type.
You might want to try finding a syntax-aware editor in which to edit schema documents, to alert you to problems of this kind.
Other syntactic issues in this fragment:
Other complexType elements have the same syntax error of putting their attribute declarations first.
If you want the type of rating to be a restriction of xs:float, then you want it to have a simple type, not a complex type.
Ditto for review_time and review_date.
The pattern on the type of review_time is not a legal regular expression: braces may contain information on the minimum and/or maximum occurrences of (strings matching) a subexpression, in a variety of forms, but they must contain something, so \d{} is not a legal expression. Drop the empty braces, or make it \d{1} if you like, or make it say what you want.
The xs:element element has no attribute named use; I think you may mean to say <xs:element name="reviews" minOccurs="1" maxOccurs="1"> ...
The use attribute does not accept the value optinal.
Get an editor!
Your xs:sequence element needs to follow immidiately on the complexType element.
Your review_date and review_time elements should be a simpleType with a restriction.
If you fix those issues your xsd seems validd.

XSD definition for simpleContent type string with attributes

I would like to define the XSD for:
<Group id="someid" parent="someid">some string</Group>
This is what I tried:
<xs:element name="Group" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="xs:string">
<xs:attribute name="id" type="xs:ID" use="required"/>
<xs:attribute name="parent" type="xs:IDREF" use="optional"/>
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
</xs:element>
I use Visual Studio for the XSD design. The validator tells me (while underlining "<xs:restriction"):
"Undefined complexType 'http://w3.org/2001/XMLSchema:string' is used as base for a complex type restriction."
It's needed to use <xs:extension> instead of <xs:restriction>:
<xs:element name="Group" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:ID" use="required"/>
<xs:attribute name="parent" type="xs:IDREF" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>

Element-Mandatory Attribute declaration in XSD Schema:

I want to declare an element to be included in a complex type declaration, and the element has a mandatory attribute: "option=MyOption", but the value of the "option" attribute could be anything, depending on the context.
That is: the attribute "option" with some unknown value should be mandatory in any document using the complex type containing this element.
Example:
<xs:element name="SpecialOption" type="xs:string"/>
<xs:complexType name="SpecialOptions">
<xs:sequence>
<xs:element ref="SpecialOption" minOccurs="1" maxOccurs="100"/>
<xs:element ref="XXX"/>
</xs:sequence>
</xs:complexType>
In this case the "SpecialOption" element in the complex type "SpecialOptions" should have this mandatory attribute.
I don't know how to declare a mandatory attribute for an element in XSD, or how to specify that the attribute must have a value that is not yet known.
You need to modify the definition of the "SpecialOption" element to include the required attribute. Update this code:
<xs:element name="SpecialOption" type="xs:string"/>
to this:
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
With this change your complex type will contain the required "Option" attribute on all instances of the "SpecialOption" element in the "SpecialOptions" complex type. Declaring the "Option" attribute to be of type xs:string will allow any value to be passed in this field.
1) This is a simple required string attribute
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
2) To require exactly one of a list of allowed values:
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="DE"/>
<xs:enumeration value="EN"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
3) One can use a range as a restriction, like in the example below.
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" use="required">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="95"/>
<xs:maxInclusive value="137"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
4) Below, the attribute is declared as a list containing decimal values. This allows an attribute to contain a subset of the specified values, e.g. Option="6 77 95".
<xs:simpleType name="Items">
<xs:restriction base="xs:decimal">
<xs:enumeration value="137"/>
<xs:enumeration value="95"/>
<xs:enumeration value="6"/>
<xs:enumeration value="77"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" use="required">
<xs:simpleType>
<xs:list itemType="Items"/>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
5) Here the attribute is declared optional, but provided with a default value ("test"), which is sometimes sufficient:
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" type="xs:string" use="optional" default="test"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
To mark an attribute as mandatory you use <xs:attribute use="required" />.
As for type, you have a choice of the built-in XSD types (xs:string etc), or you can define your own <xs:simpleType /> and use that.
UPDATE
I am not certain what you mean by the attribute must have a value that is not yet known. Does this mean that the value is a string, but can be any string? Or a decimal?
Because it's an attribute value we are talking about you are restricted to using the built-in XSD types, or defining your own xs:simpleType type based on one of the built-in types. This is where you can apply more stringent rules to the allowed value, for example by extending xs:string and adding a regular expression constraint to allowed values.
<xsd:simpleType name="UKDate">
<xsd:restriction base="xsd:string">
<xsd:pattern value="(0?[1-9]|[12][0-9]|3[01])[- /.](0?[1-9]|1[012])[- /.](19|20)\d\d"/>
</xsd:restriction>
</xsd:simpleType>
However, if there is absolutely no way of knowing what value will be used then you have the well known temporal paradox whereby you cannot restrict something at design-time to a value you only know at run-time. In this instance, surely it is only necessary to specify that the attribute must at least be present?
<xs:attribute use="required" />
Hope this answers your question a little more clearly.
Simply you can do it as the following
<xs:element name="SpecialOption">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="replace"/>
<xs:minLength value="1"></xs:minLength>
</xs:restriction>
</xs:simpleType>
</xs:element>
by this code you enforce to insert a value on the xml tag and also the white space restriction will handle to remove the white space from the xml tag.

XSD and plain text

I have a rest/xml service that gives me the following...
<verse-unit unit-id="38009001">
<marker class="begin-verse" mid="v38009001"/>
<begin-chapter num="9"/><heading>Judgment on Israel&apos;s Enemies</heading>
<begin-block-indent/>
<begin-paragraph class="line-group"/>
<begin-line/><verse-num begin-chapter="9">1</verse-num>The burden of the word of the <span class="divine-name">Lord</span> is against the land of Hadrach<end-line class="br"/>
<begin-line class="indent"/>and Damascus is its resting place.<end-line class="br"/>
<begin-line/>For the <span class="divine-name">Lord</span> has an eye on mankind<end-line class="br"/>
<begin-line class="indent"/>and on all the tribes of Israel,<footnote id="f1">
A slight emendation yields <i>
For to the <span class="divine-name">Lord</span> belongs the capital of Syria and all the tribes of Israel
</i>
</footnote><end-line class="br"/>
</verse-unit>
I used visual studio to generate a schema from this and used XSD.EXE to generate classes that I can use to deserialize this mess into programmable stuff.
I got everything to work and it is deserialized perfectly (almost).
The problem I have is with the random text mixed throughout the child nodes. The generated verse-unit objects gives me a list of objects (begin-line, begin-block-indent, etc), and also another list of string objects that represent the bits of string throughout the xml.
Here is my schema
<xs:element maxOccurs="unbounded" name="verse-unit">
<xs:complexType mixed="true">
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="marker">
<xs:complexType>
<xs:attribute name="class" type="xs:string" use="required" />
<xs:attribute name="mid" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="begin-chapter">
<xs:complexType>
<xs:attribute name="num" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="heading">
<xs:complexType mixed="true">
<xs:sequence minOccurs="0">
<xs:element name="span">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="class" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="begin-block-indent" />
<xs:element name="begin-paragraph">
<xs:complexType>
<xs:attribute name="class" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="begin-line">
<xs:complexType>
<xs:attribute name="class" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
<xs:element name="verse-num">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:unsignedByte">
<xs:attribute name="begin-chapter" type="xs:unsignedByte" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="end-line">
<xs:complexType>
<xs:attribute name="class" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
<xs:element name="end-paragraph" />
<xs:element name="end-block-indent" />
<xs:element name="end-chapter" />
</xs:choice>
</xs:sequence>
<xs:attribute name="unit-id" type="xs:unsignedInt" use="required" />
</xs:complexType>
</xs:element>
WHAT I NEED IS THIS. I need the random text that is NOT surrounded by an xml node to be represented by an object so I know the order that everything is in.
I know this is complicated, so let me try to simplify it.
<field name="test_field_0">
Some text I'm sure you don't want.
<subfield>Some text.</subfield>
More text you don't want.
</field>
I need the xsd to generate a field object with items that can have either a text object, or a subfield object. I need to no where the random text is within the child nodes.
You can try Xml Schema Mixed Content, which is well explained here: http://www.w3schools.com/schema/schema_complex_mixed.asp
I don't know much about the .net side. But this somewhat older article says that mixed mode is basically supported by xsd.exe: http://msdn.microsoft.com/en-us/magazine/cc164135.aspx
Well your problem starts here:
<xs:element name="begin-line">
<xs:complexType>
<xs:attribute name="class" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
What this means is that a "begin line" type has an attribute called class (Which means the tag can have an attribute class like so: <begin-line class="lineclass">. However it is simply a type xs:string which means that all you get is a string.
I also don't know if this is an option, but if your XML could be made to have closing tags like this line for instance:
<begin-line class="indent"/>and Damascus is its resting place.<end-line class="br"/>
XML should be like this:
<begin-line class="indent"/>and Damascus is its resting place.</begin-line class="br">
I believe that if all the "line" tags were closed properly then the XSD generator might have a better time trying to derive what is inside the "begin-line" XML tag. Indeed if this is possible then you could rename begin-line to line and begin-chapter to chapter which should make your XML much more readable.
If it's not possible to update your code, then you are going to have to try your best with the string itself. I'm not sure if verses contain pure HTML, but if so you could parse the string inside the begin-line element as XML itself, using the library to jump between values and nodes (you might have to wrap a pair of tags around the string before trying to parse it though).

Resources