I have a restriction to set on values of the element. As per the rules I want to set, following set of values are possible for my element.
<tags>
<tag>One of Audio, Video, Others.</tag>
<tag>For Audio, either Label or Record, For Video, either Studio or Producer, For Others this tag will be empty.</tag>
<tag>One of English, Spanish, French</tag>
</tags>
Now I could have set a regex pattern restriction in my XSD for a single tags element if it was plain text delimiter (,) separated values which might be
<element name="tags">
<simpleType>
<restriction base="string">
<pattern value="(Audio, (Label|Record)|Video, (Studio|Producer)|Others), (English|Spanish|French)" />
</restriction>
</simpleType>
</element>
But since I have a sequence of elements with same name tag, I am not sure it is even possible to restrict such way via XSD. I know I can restrict the values via enumeration but then I cannot group those. I want following XML to validate
<tags>
<tag>Audio</tag>
<tag>Record</tag>
<tag>English</tag>
</tags>
And following to fail validation
<tags>
<tag>Others</tag>
<tag>Record</tag>
<tag>English</tag>
</tags>
My real case is much more complex with nested restrictions, but I someone can help out in above condition, I think I can take it as a reference and solve my problem.
I don't think you can. If you have control of the schema why do you desire this specific rule set for validation? If you need this strict validation in this exact way you may need it done at the application level and not the document definition level. It appears what you really want is a way to tag different information based on certain tag "types". There really is no reason to have a list of elements all named tag, you know they are tags already from the parent elements name. Instead if you want validation based on the type of tags you should use different element types and structure your schema to validate against which types are allowed when and where. For your data this can be done using complex types and a choice model:
<xs:element name="audio">
<xs:complexType>
<xs:choice>
<xs:element name="Label" type="xs:string"/>
<xs:element name="Record" type="xs:string"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:complexType name="generic">
<xs:choice>
<xs:element name="Studio" type="xs:string"/>
<xs:element name="Producer" type="xs:string"/>
</xs:choice>
</xs:complexType>
<xs:element name="video" type="generic"/>
<xs:element name="other" type="generic"/>
<xs:element name="tags">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element ref="audio"/>
<xs:element ref="video"/>
<xs:element ref="other"/>
</xs:choice>
<xs:element name="language">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="English"/>
<xs:enumeration value="Spanish"/>
<xs:enumeration value="French"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
I took liberty for Producer, Label, Studio, and Record that you would want the values for those types as well. If not, for your original case you can just use an attribute on the parent elements instead like this:
<xs:complexType name="generic">
<xs:attribute name="meta-type">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Studio"/>
<xs:enumeration value="Producer"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
Instead of using a choice group you could use substitutionGroups but this would require each element to be derived from the same type which you may not want.
These schema's can be expanded quite easily and if you still need a generic <tag>'s list that doesn't need strict validation you could add it as part of the tags sequence definition.
Maybe someone can give you a better answer for your original requirements, but I hope this information helps.
Related
Here is an example of what I'd like to be able to do as a sample of XML (take note of the file elements):
...
<run-list>
<topic name="topic1"/>
<topic name="topic2">
<file number="2"/>
<file number="3">
/a/b/c /a/b/d /a/b/g/h/i
</file>
</topic>
</run-list>
...
The run-list element can contain any number of topic elements. The topic element may contain zero or more file elements. The file element has the number attribute (required) and may contain zero or more path strings (the list).
I can't figure out how to define a schema type to allow for the definition of the file element as described above. I need the file element to have the number attribute and I'd like to be able to specify an optional list of path values. I have been able to define simple list types for other situations, but they don't have any attributes.
I have been able to do something that is close to this, but needed to define another schema type for the paths and implement it as an element within the file element. So I'd have something like this:
...
<file number="3">
<path>/a/b/c</path>
<path>/a/b/d</path>
<path>/a/b/g/h/i</path>
</file>
...
I'd like to avoid having to define a separate schema type and element to specify the path(s) under a given file element.
Any help would be appreciated.
I think I figured it out. Here's the schema that seems to work:
<xs:complexType name="TestSpecification">
<xs:sequence>
<xs:element name="topic" type="TopicSpecification"
minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TopicSpecification">
<xs:sequence>
<xs:element name="file" type="FileSpecification" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="FileSpecification">
<xs:simpleContent>
<xs:extension base="EntityPathList">
<xs:attribute name="number" type="xs:positiveInteger" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="EntityPathList">
<xs:list itemType="xs:string" />
</xs:simpleType>
If anyone sees any potential problems with this, suggestions on how to improve or alternatives, please feel free to comment.
I would like to know if it is possible to validate attribute names by pattern using XML Schema. In other words, I would like to describe a set of acceptable attribute names for a given type, using a pattern (such as a regular expression).
Lets say I have the following XML data I would like to validate:
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="http://mywebsite.com/myns">
<somename data-someattr1="value1"
data-someattr2="value2"/>
</root>
How can I describe that attributes of elements with name "somename" can only have attributes with name beginning by "data-"? Is this even possible?
Try something along the lines of:
<xs:simpleType name="somename">
<xs:restriction base="xs:string">
<xs:pattern value="^data-"/>
</xs:restriction>
</xs:simpleType>
The regex ^data- means "beginning with 'data-'", as you require.
EDIT:
I misunderstood the question, sorry... Here is a more relevant answer:
As I understand it, you cannot pattern match attribute names in an XSD - so there is no solution to your problem using an XSD alone. However, you may find one of the following XML schema elements helpful in constructing a solution:
XML choice (http://www.w3schools.com/schema/el_choice.asp) - so you could (possibly?) list all "data-" attribute names explicitly.
XML any (http://www.w3schools.com/schema/schema_complex_any.asp) - so you could then perform any additional validation steps via some other method.
Well, as it was said you can't validate attribute names, but you still can go different way and transform your xml to some kind of:
<root>
<element>
<data name='data-attr1' value='v1'/>
<data name='data-attr2' value='v2'/>
<data name='data-attr3' value='v3'/>
</element>
</root>
So now you can validate fake attribute name - data name='data-attr1' as well as values. Your schema might look like this:
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' elementFormDefault='qualified' attributeFormDefault='unqualified'>
<xs:element name='root'>
<xs:complexType>
<xs:sequence>
<xs:element name='element'>
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs='10' name='data'>
<xs:complexType>
<xs:attribute name='name' use='required'>
<xs:simpleType>
<xs:restriction base='xs:string'>
<xs:pattern value='data-.*' />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name='value' use='required' />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I am using gsoap for implementing the soap stack of my tr069 client completely written in C language.
The xsd file i am using is cwmp-1-2.xsd from broadbanforum.
In cwmp-1-2.xsd , The ParameterValueStruct is defined as :
<xs:complexType name="ParameterValueStruct">
<xs:sequence>
<xs:element name="Name">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Value" type="xs:anySimpleType"/>
</xs:sequence>
</xs:complexType>
"Value" element is polymorphic type and so, "value" must show the actual data type of the parameter.
e.g. <Value xsi:type="xsd:integer"> or <Value xsi:type="xsd:boolean"> depending on the parameter type it has to show.
But it is only showing <Value xsi:type="xsd:anySimpleType">0</Value> for all cases.
I am not able to find any solution as to how I will be able to implement the polymorphic attribute of the element using C.
Do I have to modify typemap.dat or dom.h ??
I'm trying to build an element type that keep a list of change element type that is the base type of several other child type. I got this code :
<xs:complexType name="change_list" >
<xs:annotation>
<xs:documentation>List of changes.</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:choice minOccurs="1" maxOccurs="unbounded" >
<xs:element name="change" type="aos:change" >
<xs:annotation>
<xs:documentation>Generic or specific type of change.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="activate" type="aos:activate" >
<xs:annotation>
<xs:documentation>Change that will activate an element or do nothing if already activated.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="deactivate" type="aos:deactivate" >
<xs:annotation>
<xs:documentation>Change that will deactivate an element or do nothing if already deactivated.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="switch" type="aos:switch" >
<xs:annotation>
<xs:documentation>Change that will activate the element if deactivated or deactivate it if activated.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="transform" type="aos:transform" >
<xs:annotation>
<xs:documentation>
Change that will modify the geometric state of the element
by applying one or several geometric transformations.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
</xs:sequence>
Im' using CodeSynthesis to generate C++ code.
Now, that seems overkill because here we clearly define access to different types. I think what I want is something simpler like :
List of changes.
<xs:sequence>
<xs:choice minOccurs="1" maxOccurs="unbounded" >
<xs:element name="change" type="aos:change" >
<xs:annotation>
<xs:documentation>Generic or specific type of change.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
</xs:sequence>
Now that don't allow me to have different tags for different subtypes of changes.
So I thought maybe a good solution might be to use substitution group.
But then I would loose the ability to use the specific sub-type's attributes and elements.
Is the original solution good to do that (having a list of base type object that can get child types too)?
Dont know if you still need an answer... But the following schema does what you need.
First of all the base type and two concrete subtypes (make sure, that your base class has abstract="true" set):
<xs:complexType abstract="true" name="BaseTask">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ConcreteTask1">
<xs:complexContent>
<xs:extension base="BaseTask">
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ConcreteTask2">
<xs:complexContent>
<xs:extension base="BaseTask">
<xs:sequence>
<xs:element name="Description" type="xs:string" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Then adding a list that holds elements that are subtypes of BaseTask:
<xs:element name="TaskList">
<xs:complexType>
<xs:sequence>
<xs:element name="Tasks" minOccurs="0" maxOccurs="unbounded" type="BaseTask" />
</xs:sequence>
</xs:complexType>
</xs:element>
The xml then looks like this:
<TaskList>
<Tasks xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ConcreteTask1">
<Name>Foo1</Name>
</Tasks>
<Tasks xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ConcreteTask2">
<Name>Foo2</Name>
<Description>Test</Description>
</Tasks>
</TaskList>
What you want is not possible in xml-schema. You can extend (or restrict) a defined type but then this is a new type. Subtyping polymorphism (inclusion polymorphism) doesn't exist in xml-schema.
It sounds like what you want is a list of changes, but you also want the type of change recorded in the list (activate, switch, etc).
What I would do is make a simple element called ChangeType element that would have a "type" attribute whose data type would be another element, ChangeTypeType which would be an enum of your valid changed types. For example:
<element name="ChangeList" type="ChangeListType"/>
<complexType name="ChangeListType">
<annotation>
<documentation>
A list of changes
</documentation>
</annotation>
<sequence>
<element name="change" type="ChangeType" minOccurs="1" maxOccurs="unbounded">
<annotation>
<documentation>
A change event
</documentation>
</annotation>
</element>
</sequence>
</complexType>
<complexType name="ChangeType">
<annotation>
<documentation>
A change unit
</documentation>
</annotation>
<attribute ref="typeOfChange" use="required"/>
</complexType>
<attribute name="typeOfChange" type="ChangeTypeType">
<annotation>
<documentation>
The kind of change
</documentation>
</annotation>
</attribute>
<simpleType name="ChangeTypeType">
<annotation>
<documentation>
Describes the types of allowed changes
</documentation>
</annotation>
<restriction base="token">
<enumeration value="activate"/>
<enumeration value="activate"/>
<enumeration value="switch"/>
<enumeration value="transform"/>
</restriction>
</simpleType>
This would give you an XML document like:
<ChangeList>
<change typeOfChange="activate/>
<change typeOfChange="switch/>
<change typeOfChange="transform/>
</ChangeList>
I am newbie in xml schema. Is there any possiblility to define that element starts with some characater or symbol. I mean to say, <xs:element minOccurs="1" maxOccurs="1" name="Header">
<xs:complexType>
<xs:sequence>
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="NAME_STUDENTS">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
is there any possible way to define a pattern or tag in xml schema that name of student starts with 'P'??And schema should recognize the text as element NAME_STUDENTS only if the text starts with 'P'
I'm not sure if I fully understand your question but concerning the name element restriction you should look into Xml Schema Regular Expressions.
In your case this would look like this:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:element name="Header">
<xs:complexType>
<xs:sequence>
<xs:element name="NAME_STUDENTS" type="filtered-students" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="filtered-students">
<xs:restriction base="xs:string">
<xs:pattern value="^[P]?"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
... but I must confess I'm not really a regex hero so you may want to check the pattern with somebody more proficient.