I would like to specify using xsd an xml-file of the form:
<root xsi:noNamespaceSchemaLocation="test2.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<mult>
<end />
<one>
<end />
</one>
<end />
<mult>
<end />
</mult>
<mult />
</mult>
</root>
That is, both, mult and end, instantiate a common abstract-type.
I am not clear how to define the type for mult without introducing further xml-elements as follows:
<root xsi:noNamespaceSchemaLocation="test2.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<mult>
<value>
<end />
</value>
<value>
<one>
<end />
</one>
</value>
<value>
<end />
</value>
<value>
<mult>
<value>
<end />
</value>
</mult>
</value>
<value>
<mult />
</value>
</mult>
</root>
for this latter file I can use:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="TYPE_end" />
<xs:complexType name="TYPE_one">
<xs:complexContent>
<xs:extension base="TYPE_abstract" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="TYPE_mult">
<xs:sequence>
<xs:element name="value" type="TYPE_one" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TYPE_abstract">
<xs:choice>
<xs:element name="end" type="TYPE_end" />
<xs:element name="one" type="TYPE_one" />
<xs:element name="mult" type="TYPE_mult" />
</xs:choice>
</xs:complexType>
<xs:element name="root" type="TYPE_abstract"/>
</xs:schema>
However, I do not know how to avoid the additional value-tag.
I could duplicate the list of elements as in the following example but this duplication is not nice as well...
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="TYPE_end" />
<xs:complexType name="TYPE_one">
<xs:complexContent>
<xs:extension base="TYPE_abstract" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="TYPE_mult">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="end" type="TYPE_end" />
<xs:element name="one" type="TYPE_one" />
<xs:element name="mult" type="TYPE_mult" />
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TYPE_abstract">
<xs:choice>
<xs:element name="end" type="TYPE_end" />
<xs:element name="one" type="TYPE_one" />
<xs:element name="mult" type="TYPE_mult" />
</xs:choice>
</xs:complexType>
<xs:element name="root" type="TYPE_abstract"/>
</xs:schema>
Any ideas how to provide a better solution?
Without more information about the rules for your XML, the following looks like it would work
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2016 Developer Bundle Edition 14.1.4.6649 (https://www.liquid-technologies.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="TYPE_abstract">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="end" />
<xs:element name="one" type="TYPE_abstract" />
<xs:element name="mult" type="TYPE_abstract" />
</xs:choice>
</xs:complexType>
<xs:element name="root" type="TYPE_abstract" />
</xs:schema>
Related
My system parses two XML files (via JAXB unmarshalling and xjc generated code)
componentModel.xml : generated from a modeling tool
detailedDesign.xml : manual, to add informations
In order to avoid to code checks upon content and structures, each file is validated with its own XSD
componentModel.xsd
detailedDesign.xsd
Both of these xsd inclulde "utilities.xsd" where common complex and simple types are defined
All works well
I now want to add consistency check :
unicity of Ids (names of components)
components in "detailsDesign" must refers one of the components in "componentModel" via the "name" and "nameRef" attributes
Here are the structures (i've simlplified names and structures in files to show only relevant informations)
Note : as you can see, i don't use any namespace except the default one
componentModel.xml
<?xml version="1.0" encoding="UTF-8"?>
<componentModel>
<components>
<component name="id1"> ... </component>
<component name="id1"> ... </component>
<component name="id2"> ... </component>
</components>
</componentModel>
componentModel.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:include schemaLocation="utilities.xsd" />
<xs:complexType name="CMComponent">
<xs:complexContent>
...
<xs:attribute name="name" type="MUUpperFirstName" use="required" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="CMComponents">
<xs:sequence>
<xs:element name="component" type="CMComponent" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="CMComponentModel">
<xs:complexContent>
<xs:sequence>
<xs:element name="components" type="CMComponents">
<!-- Key used to check "name" unicity and as a ref by nameRef attribute in detailedDesign model -->
<xs:key name="componentNameKey">
<xs:selector xpath="component" />
<xs:field xpath="#name" />
</xs:key>
</xs:element>
<xs:element name="functionalChains" minOccurs="0" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="name" type="MUModelName" use="required" />
</xs:complexContent>
</xs:complexType>
<xs:element name="componentModel" type="CMComponentModel" />
</xs:schema>
utilities.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="MUString">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="MUUpperFirstName">
<xs:restriction base="MUString">
<xs:pattern value="([A-Z]+[a-zA-Z0-9]*[.])*[A-Z]+[a-zA-Z0-9]*"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MUReferenceName">
<xs:restriction base="MUString">
<xs:pattern value="([A-Z]+[a-zA-Z0-9]*[.])*[a-zA-Z]+[a-zA-Z0-9]*"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
detailedDesign.xml
<?xml version="1.0" encoding="UTF-8"?>
<detailedDesignModel>
<components>
<component nameRef="id1"> ... </component>
<component nameRef="id2"> ... </component>
<component nameRef="id3"> ... </component>
</components>
</detailedDesignModel>
detailedDesign.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="utilities.xsd" />
<xs:include schemaLocation="componentModel.xsd" />
<xs:complexType name="DDMComponent">
<xs:complexContent>
...
<xs:attribute name="nameRef" type="MUReferenceName" use="required" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="DDMComponents">
<xs:sequence>
<xs:element name="component" type="DDMComponent" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="DDMDetailDesignModel">
<xs:complexContent>
<xs:sequence>
<xs:element name="components" type="DDMComponents">
<xs:keyref name="componentNameKeyRef" refer="componentNameKey">
<xs:selector xpath="component" />
<xs:field xpath="#nameRef" />
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexContent>
</xs:complexType>
<xs:element name="detailDesignModel" type="DDMDetailDesignModel" />
</xs:schema>
It works for unicity of 'name' attribute among components (error retrieved from ValidationEventHandler set on unmarshaller) :
Duplicate key value [id1] declared for identity constraint of element "components".
But i can't get the "keyref" functionnality working (error retrieved from ValidationEventHandler set on unmarshaller) :
Identity Constraint error: identity constraint "KeyRef#272ed83b" has a keyref which refers to a key or unique that is out of scope.
How can i make the keyRef to see the Key defined in the orther XSD file
Thanks
Matth
Hi I have this kind of XML
I would like to write an XML that validates this data:
<?xml version="1.0" encoding="UTF-8"?>
<Entry attribute1="value1" attribute2="Value2">
<subEntry tagX="xValue1" tagy="yValue"/>
</Entry>
but doesn't validate
<?xml version="1.0" encoding="UTF-8"?>
<Entry attribute1="value1" attribute2="Value2">
<subEntry tagX="xValue1" tagy="yValue"/>
<subEntry tagX="xValue1" tagy="yValue"/>
</Entry>
I would like to restrict the number of subEntries:
The maxOccurs of sequence don't check the number of subEntries.
The XSD is :
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Entry">
<xs:complexType>
<xs:sequence>
<xs:element ref="subEntry"/>
</xs:sequence>
<xs:attribute1 name="dateEmission" type="xs:dateTime" use="required"/>
<xs:attribute2 name="emetteur" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Entry">
<xs:complexType>
<xs:attribute name="tagX" type="xs:string" use="required"/>
<xs:attribute name="tagy" type="xs:decimal" use="optional"/>
</xs:complexType>
</xs:element>
</xs:schema>
You need to add maxOccurs on the element declaration. Change it to below
<xs:sequence>
<xs:element ref="subEntry" maxOccurs="1" />
</xs:sequence>
I have just made my first attempt at XSD.
When I try and validate my XML against my XSD, I get the error:
Cannot find the declaration of element 'linkage'.
Below I give my XSD and a cut down version of my XML. I've tried adding a namespace qualifier to the top element in my XML and also to every element (changing the XSD to qualified) and it did not help. I'm obviously making a basic mistake. As I'm new to XSD, if you could include what I need to change in my XML and/or XSD I would be very grateful.
XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.stephenwaring.me.uk/android/nestedsettings"
xmlns="http://www.stephenwaring.me.uk/android/nestedsettings"
elementFormDefault="unqualified">
<xs:element name="linkage">
<xs:complexType>
<xs:sequence>
<xs:element name="preference-screen" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="parent" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="child" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="key" type="xs:token" use="required" />
<xs:attribute name="reformat" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="keyed" />
<xs:attribute name="preference-screen" type="xs:token" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="keyed"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="defaults"/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="defaults">
<xs:attribute name="html" type="xs:boolean" />
<xs:attribute name="prefix" type="xs:string" />
<xs:attribute name="suffix" type="xs:string" />
<xs:attribute name="separator" type="xs:string"/>
<xs:attribute name="reformat" type="xs:boolean" />
<xs:attribute name="shaddow" type="xs:boolean" />
<xs:attribute name="child-summary" type="xs:boolean" />
<xs:attribute name="shadow-separator" type="xs:string"/>
</xs:attributeGroup>
<xs:attributeGroup name="keyed">
<xs:attributeGroup ref="defaults" />
<xs:attribute name="key" type="xs:token" use="required" />
</xs:attributeGroup>
</xs:schema>
Cut down XML:
<?xml version="1.0" encoding="UTF-8"?>
<linkage
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://stevewaring.me.uk/android/nestedsettings nestedsettings.xsd"
xmlns="http://www.stevewaring.me.uk">
<preference-screen
key="preferences1">
<parent
key="prefFruit"
preference-screen="preferences2">
<child key="prefFruit1"/>
<child key="prefFruit2"/>
</parent>
</preference-screen>
</linkage>
Your XSD defines elements in http://www.stephenwaring.me.uk/android/nestedsettings whereas your document element is in http://www.stevewaring.me.uk. Make them to agree, one way or the other, and it should take care of the error you're having.
I've added a fixed XML, there's another issue related to use of unqualified elements.
<?xml version="1.0" encoding="UTF-8"?>
<linkage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.stephenwaring.me.uk/android/nestedsettings nestedsettings.xsd" xmlns="http://www.stephenwaring.me.uk/android/nestedsettings">
<preference-screen xmlns="" key="preferences1">
<parent key="prefFruit" preference-screen="preferences2">
<child key="prefFruit1"/>
<child key="prefFruit2"/>
</parent>
</preference-screen>
</linkage>
I've created a key/keyref on the root element in order to create document-wide uniqueness based on the specified element.
Therefore, via .//foo/#name every occurrence of #name across all instances of foo must be unique; likewise for .//bar/#name. This seems to be working fine. These are referenced by .//foo-ref/#name-ref and .//bar-ref/#name-ref respectively, also defined at the root node.
However, I've gathered that one cannot create an optional key, and this is presenting a bit of a problem. Semantically, by the nature of the conforming documents, a key is not required on every single instance of foo or bar. The instances of foo-ref/#name-ref would obviously need to target an existing foo/#name, but it isn't semantically invalid for a foo to be without a #name.
Is there any work-around for this? I don't like the idea of consumers having to define a key for every single element, when reasonably only a handful will need them.
Here's the example schema (of course, I'm not deploying some foobar schema, but the structure is identical; this is just a testing schema I've been toying with)
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="ref">
<xs:attribute name="name-ref" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="obj">
<xs:attribute name="name" type="xs:string" use="optional" />
</xs:complexType>
<xs:complexType name="foo">
<xs:complexContent>
<xs:extension base="obj">
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="foo" type="foo" />
<xs:element name="bar" type="bar" />
<xs:element name="foo-ref" type="foo-ref" />
<xs:element name="bar-ref" type="bar-ref" />
</xs:choice>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="foo-ref">
<xs:complexContent>
<xs:extension base="ref" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="bar">
<xs:complexContent>
<xs:extension base="obj">
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="bar" type="bar" />
<xs:element name="qux" type="qux" />
<xs:element name="bar-ref" type="bar-ref" />
</xs:choice>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="bar-ref">
<xs:complexContent>
<xs:extension base="ref" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="qux">
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="foo" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:key name="foo">
<xs:selector xpath=".//foo" />
<xs:field xpath="#name" />
</xs:key>
<xs:key name="bar">
<xs:selector xpath=".//bar" />
<xs:field xpath="#name" />
</xs:key>
<xs:keyref name="foo-ref" refer="foo">
<xs:selector xpath=".//foo-ref" />
<xs:field xpath="#name-ref" />
</xs:keyref>
<xs:keyref name="bar-ref" refer="bar">
<xs:selector xpath=".//bar-ref" />
<xs:field xpath="#name-ref" />
</xs:keyref>
</xs:element>
</xs:schema>
Addendum
Just following up with my revisions thanks to #PetruGardea. So unique can be referenced by a keyref, who knew? (not me apparently)
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="foo" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:keyref name="foo-ref" refer="foo">
<xs:selector xpath=".//foo-ref" />
<xs:field xpath="#name-ref" />
</xs:keyref>
<xs:keyref name="bar-ref" refer="bar">
<xs:selector xpath=".//bar-ref" />
<xs:field xpath="#name-ref" />
</xs:keyref>
<!--
the use of xs:unique here, in lieu of xs:key allows for
nullable "keys", retaining referential integrity with the
above defined keyrefs. awesome possum.
-->
<xs:unique name="foo">
<xs:selector xpath=".//foo" />
<xs:field xpath="#name" />
</xs:unique>
<xs:unique name="bar">
<xs:selector xpath=".//bar" />
<xs:field xpath="#name" />
</xs:unique>
</xs:element>
Use xsd:unique; unlike a key, its matched value is either unique or nil (nil or not present).
Example:
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="uk" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="fk" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:unique name="uq">
<xsd:selector xpath="uk"/>
<xsd:field xpath="#name"/>
</xsd:unique>
<xsd:keyref name="fk" refer="uq">
<xsd:selector xpath="fk"/>
<xsd:field xpath="#name"/>
</xsd:keyref>
</xsd:element>
</xsd:schema>
Sample (valid) XML:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<uk name="name1"/>
<uk />
<fk/>
<fk name="name1"/>
</root>
For the following xml need a schema.
<?xml version="1.0" encoding="UTF-8"?>
<overall_operation>
<operation type="list_products">
<ops_description>Listing all the products of a company</ops_description>
<module>powesystem</module>
<comp_name>APC</comp_name>
<prod_price>50K$</prod_price>
<manf_date>2001</manf_date>
<pool_name>Electrical</pool_name>
<fail_retry>2</fail_retry>
<storage_type>avialble</storage_type>
<storage_check>false</storage_check>
<api_type>sync</api_type>
<product_name>transformer</product_name>
</operation>
<operation type="search_product">
<ops_description>Search the products of a company from the repository</ops_description>
<module>high-voltage</module>
<module>powesystem</module>
<comp_name>APC</comp_name>
<pool_name>Electrical</pool_name>
<fail_retry>2</fail_retry>
<storage_type>avialble</storage_type>
<storage_check>false</storage_check>
<api_type>sync</api_type>
<product_name>setup-transformer</product_name>
</operation>
</overall_operation>
Here different elements with operation like list_products,search_products and so on.
Each element will have some common attributes such as ops_description,module and so on.
Also some of the unique attributes for each element such as prod_price,manf_date etc.
I want to have a xml schema to validate. Some of the attributes also optional.
I tried using abstract and derived but could not make it work.
What you want to achieve is not possible with xml schema. The definition states that every element or attribute must be validated on its own and without reference to other elements or attributes.
The best solution you can get is to group optional but dependent elements:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="overall_operation">
<xs:complexType>
<xs:sequence>
<xs:element name="operation" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ops_description" />
<xs:element name="module" minOccurs="1" maxOccurs="2" />
<xs:element name="comp_name" />
<xs:group ref="price_and_date" minOccurs="0" maxOccurs="1" />
<xs:element name="pool_name" />
<xs:element name="fail_retry" />
<xs:element name="storage_type" />
<xs:element name="storage_check" />
<xs:element name="api_type" />
<xs:element name="product_name" />
</xs:sequence>
<xs:attribute name="type" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:group name="price_and_date">
<xs:sequence>
<xs:element name="prod_price" />
<xs:element name="manf_date" />
</xs:sequence>
</xs:group>
</xs:schema>
Use minOccurs and maxOccurs attributes to control optional elements and groups.