XML Schema - only one element should have attribute set to true - xsd

How can i define an boolean attribute that can be set "true" only in one element.
Following snippet must be invalid.
<products>
<product featured="yes">Prod 1</product>
<product featured="yes">Prod 2</product>
</products>

You can't do that with XML Schemas.
You can define attributes on an element, but not limit them to one instance of the element.

You could add an attribute in products element indicating which product is featured.

You can't do this with XMLSchema. If you want to specify these constraints in an XML environment try Schematron (http://www.schematron.com/).

You could do the following...
<products>
<product featured="Yes">Prod 1</product>
<product>Prod 2</product>
</products>
Then use a unique element to constrain the attribute thus...
<xs:unique name="UniqueFeaturedProduct">
<xs:selector xpath="product"/>
<xs:field xpath="#featured"/>
</xs:unique>
If you were to restrict the 'featured' attribute to an optional enumeration of one value "Yes" then there could only be one featured attribute. Something like this...
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="products">
<xs:complexType>
<xs:sequence>
<xs:element name="product" type="productType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="UniqueFeaturedProduct">
<xs:selector xpath="product"/>
<xs:field xpath="#featured"/>
</xs:unique>
</xs:element>
<xs:simpleType name="featuredType">
<xs:restriction base="xs:string">
<xs:enumeration value="Yes"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="productType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="featured" type="featuredType" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>

My reply is this way, 'cause I cannot add comments yet.
"You could add an attribute in products element indicating which product is featured."
This solution lead to another problem: checking if the attribute points to existing element.
<products featured_id="3">
<product id="1">Prod 1</product>
<product id="2">Prod 2</product>
</products>

Related

XML Schema same attributes names but different specific attribute sets of values?

I wish to create a repeating same named element with two attributes for which the values of each are tied to each other. i.e.
<anElement id="R1" description="Some definition for R1"/>
<anElement id="R2" description="Some definition for R2"/>
Ideally I would define "groups" of id and description attributes together and reference one of the groups for each instance of anElement element.
<complexType name="RElements">
<choice>
<element name="anElement" type="R1Group"/>
<element name="anElement" type="R2Group"/>
</choice>
</complexType>
<complexType name="RElementsType">
<sequence>
<element ref="RElements" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
</complexType>
But Choice doesn't allow multiples of the same element name. I see discussions about how to have multiple elements of the same name but none allow additional attributes let alone having attributes tied to each other. The only way that I can get close is by having a different named element based on the id. i.e.
<R1 id="R1" description="Some definition for R1"/>
<R2 id="R2" description="Some definition for R2"/>
Any suggestions?
You need to provide more information.
Basically to achieve the XML you have provided a simple schema like this would suffice.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2015 Developer Bundle Edition 13.0.3.5737 (http://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="RootElement">
<xs:complexType>
<xs:sequence>
<xs:element name="anElement" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:string" />
<xs:attribute name="descritpion" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
However you mention that the attribute values id and description are linked, you may be able to constrain these, but you need to provide more info. Also I'm not sure why you are looking at choices? Its difficult to see what your attempting give you only provide snippets of the schema
To include the constraints described in later comments the following schema would allow this, but force a change in the XML structure
<AnElement id="E1"> Exterminator serial <ref id="E1"/> </AnElement>
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2015 Developer Bundle Edition 13.0.0.5686 (http://www.liquid-technologies.com)-->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="RootElement">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="AnElement">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="ref" minOccurs="0">
<xs:complexType>
<xs:attribute name="id" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="optional" />
</xs:complexType>
<xs:key name="IDVal">
<xs:selector xpath="." />
<xs:field xpath="#id" />
</xs:key>
<xs:keyref name="IdRef" refer="IDVal">
<xs:selector xpath="ref" />
<xs:field xpath="#id" />
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

XML Schema Question

Is it possible to define an XML Schema (XSD) to correctly describe a document such as the following?
<root>
<str name="status">success</str>
<str name="message">Your request has been processed successfuly.</str>
</root>
The problem might be that the <str> tags have an attribute (name) as well as string values.
I would be grateful if anyone could come up with an XML Schema for this piece of XML, since I am kind of stuck at this point. My best attempt so far is shown below, but botice that the <str> element cannot have a type (such as xsd:string) in this context.
<xs:element name="object">
<xs:complexType>
<xs:sequence>
<xs:element name="str" minOccurs="2" maxOccurs="2">
<xs:complexType>
<xs:sequence>
<xs:element name="productName" type="xs:string"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
Your constraints are not entirely clear, so a number of schemas would validate the XML depending on how loose/tight you would want the validation to be. This example shows a schema that mandates exactly two elements inside the element and they must have a "name" attribute with the values "status" or "message".
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="str" type="StrType" minOccurs="2" maxOccurs="2"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="StrType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="StrAttribute" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="StrAttribute">
<xs:restriction base="xs:string">
<xs:enumeration value="status"/>
<xs:enumeration value="message"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Of course, this would allow two elements both with the name attribute set to "message", or with "message" first, then status. I believe the schema cannot define a sequence containing two elements of the same name but different types which you would need if you required the validation to ensure that the first always contained "status" and the second one contained "message".

Why won't XML Schema allow me to define a one-to-many key? And how do I do so?

I'm falling over on a frustrating, arbitrary restriction in XML Schema. For some reason, it insists that PK-FK relationships have to be one-to-one. Why?
For example, given the schema:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="FutureSchema"
targetNamespace="http://tempuri.org/FutureSchema.xsd"
elementFormDefault="unqualified"
xmlns="http://tempuri.org/FutureSchena.xsd"
xmlns:mstns="http://tempuri.org/FutureSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="FUTUREFILE">
<xs:complexType>
<xs:sequence>
<xs:element name="Configuration">
<xs:complexType>
<xs:sequence>
<xs:element name="Experiments">
<xs:complexType>
<xs:sequence>
<xs:element name="Experiment">
<xs:complexType>
<xs:attribute name="ID" type="xs:integer"/>
<xs:attribute name="Profile" type="xs:integer"/>
</xs:complexType>
<xs:keyref name="dummy" refer="LP">
<xs:selector xpath="Experiment"/>
<xs:field xpath="#Profile"/>
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="LP">
<xs:selector xpath="*/Configuration/Profiles/Profile"/>
<xs:field xpath="#ID"/>
</xs:key>
</xs:element>
<xs:element name="Profiles">
<xs:complexType>
<xs:sequence>
<xs:element name="Profile">
<xs:complexType>
<xs:attribute name="ID" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
And an example instance:
<?xml version="1.0" encoding="utf-8" ?>
<b:FUTUREFILE xmlns:b="http://tempuri.org/FutureSchena.xsd">
<Configuration>
<Experiments>
<Experiment ID="1" Profile="1"/>
<Experiment ID="2" Profile="1"/>
</Experiments>
<Profiles>
<Profile ID="1"/>
</Profiles>
</Configuration>
</b:FUTUREFILE>
Document validation throws an error if I define <Experiment ID="1" FK="1"/><Experiment ID="2" FK="1"/>, for example; i.e. more than one Experiment may not reference the same Profile. But why else would I want to use a key relationship? What use is a key relationship at all if I can't do something so fundamental?
OK, if and won't let me do this, how should I?
edit #1: As requested, I've padded out my code sample to include the full schema and a basic instance.
edit #2: Interesting. SharpDevelop's XML editor (as opposed to Visual Studio's) doesn't seem to object. It doesn't object to the foreign key value referring to a nonexistent primary key either (which IMO it should) but it's a start.
What wasn't clear ?... My english, it's all :-)
Some remarqs, I'm not sure it's solution :
In exemple instance, it's best to use xmlns:b="http://tempuri.org/FutureSchema.xsd">, and not xmlns:b="http://tempuri.org/FutureSchena.xsd"> (n -> m).
Also it's best to put b: in front of all elements names.
According to your schema, you can't have two Experiment in Experiments, only one.
On xsd, put <xs:keyref name="dummy" refer="mstns:LP">, that works best for me ; it's because xpath expression doesnt't understand default namespace, see Correct way to use key in xsd.

XSD any element

I'm trying to create a list that some of the elements are defined and some are not, without priority to order.
I tried it this way, with an any element:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="object" mixed="true">
<xs:choice>
<xs:element name="value" minOccurs="1" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:enumeration value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:any namespace="##any" processContents="skip"/>
</xs:choice>
</xs:complexType>
<xs:element name="object" type="object"/>
</xs:schema>
And it tells me this error:
:0:0: error: complex type 'object' violates the unique particle
attribution rule in its components 'value' and '##any'
Can someone help me out solve the problem?
You cannot define your schema like that, it violates the unique particle attribution rule: the parser cannot tell whether a "value" element it finds in the document should be validated against "value" or against "any".
Here is a good overview.
Consider using two namespaces and using xsd:any with a namespace, this will remove the problem.

How to validate empty string value tag in xsd

I have an xml file which is having some date values and other datatypes.
<Purchasedate Name="purcaseDate" value=""/>
I am validating these xml files with a xsd file.
In xsd shcema I have written a regular expression pattern for dd/mm/yyyy format.
This is working fine if value attribute have a value.
My pattern is validating against the value attribute.
The field (purchasedate) is not mandatory.
if value="", this means my pattern is validating against an empty string also, which is not mandatory.
I need to validate the optional field
and i am using <xs:attribute name="PurchaseDate" use="optional"> also.
I need to validate this field when value tag is not empty.
That's too easy ..
Just all you have to do is to include empty string specification in your pattern
This is the way to do that ..
<xs:pattern value="|(Regular_pattern_goes_here)"/>
For your reference I have written a sample chunks of codes .. just go through them ..
sample XML:
<?xml version="1.0" encoding="utf-8"?>
<xmln xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com XMLFile1.xsd" xmlns="http://www.xsdef.com/xml/123">
<Purchasedate Name="purcaseDate" value=""/>
</xmln>
sample XSD:(includes custom type def)
<xs:schema xmlns:xsLocal="http://www.xsdef.com/xml/123" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.xsdef.com/xml/123" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="xmln">
<xs:complexType>
<xs:sequence>
<xs:element name="Purchasedate">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="value" type="xsLocal:CUSTOM_DATE" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="CUSTOM_DATE">
<xs:restriction base="xs:string">
<xs:pattern value="|((01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31)/(01|02|03|04|05|06|07|08|09|10|11|12)/[1-2][0-9][0-9][0-9])"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
try adding this attribute nillable="true" into the xml tag definition
Also you can take a look at his link http://www.zvon.org/xxl/XMLSchemaTutorial/Output/ser_over_st0.html
Best Reagds,
Iordan
The '?' character in the Regex means that the character before it must occur 0 or 1 times.
So in order to solve your issue you need to wrap the regex in parenthesis and put a questionmark at the end:
<xs:simpleType name="PurchaseDateType">
<xs:restriction base="xs:string">
<xs:pattern value="(Regular_pattern_goes_here)?"/>
</xs:restriction>
</xs:simpleType>
Use this type on your field and you should be fine
If you control the syntax of the XML, you should consider defining the element as follows. Since XML-Schema already provides a date type, you should use it unless you have a really good reason. I say this because it will make it easier for others to use the xml and for you to use better code frameworks later. I didn't include the "name" attribute because it seemed redundant to the element name.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Purchasedate" nillable="true" type="xs:date"/>
<xs:element name="Purchasedate2">
<xs:complexType>
<xs:attribute name="value" type="xs:date"/>
</xs:complexType>
</xs:element>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="Purchasedate"/>
<xs:element minOccurs="0" ref="Purchasedate2"/>
</xs:sequence>
</xs:complexType>
</xs:element>

Resources