I have defined some global elements in my xsd schema. Now if the xml file contains any of the global elements alone(without any other root element) the validation should not allow this. But in my case if only the global element is present, the file is validated successfully.
In my case there is GROUP element which is a global element. This element should always be contained in a CASE element but if remove the CASE element the xml file is still validated successfully.
I cannot make the GROUP element as a local element as it has some complex logic(recursive calls to itself) and used at more than one place. Moreover when I tried to make it as local it gave me errors.
Now is there any solution to restrict it not to be used outside the CASE element.
Example(Allowed):
<?xml version="1.0" encoding="utf-8" ?>
<CASE>
<GROUP>
</GROUP>
</CASE>
Not Allowed:
<?xml version="1.0" encoding="utf-8" ?>
<GROUP>
</Group>
I'm sorry but there is no way in XML Schema to specify which global element is the only one allowed as a root. You may need to look at other techniques to validate this requirement (such as embedding Schematron rules
You could try a workaround: wrap your <GROUP> element inside a <xs:group name="someName"> element so that this group contains only your <GROUP> element. (eh, a bit confusing because of these names...) In this case, whenever you need to refer to your global <GROUP> element, you should refer to that "someName" group instead.
This workaround may not be applicable for you if your recursive element definition is complicated.
Have you tried to make the Group element local, but giving it a global type to allow recursion and reuse?
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Case" type="CaseType"/>
<xs:complexType name="CaseType">
<xs:sequence>
<xs:element name="Group" type="GroupType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="GroupType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Group" type="GroupType"/>
<xs:element name="Case" type="CaseType"/>
</xs:choice>
</xs:complexType>
</xs:schema>
Related
So I found this post which is very similar to what I want to achieve, but I can't quite figure out if it's not possible to do what I am attempting, or if I'm just missing something...
Use XML Schema to extend an element rather than a complexType
The gist is that I have an XSD that contains a defined Element. I would prefer not to edit this original xsd file. Is there any way for me to extend the Element so that I also can add my own attributes, "attributeC"?
The other post creates a new complexType of fooType, and places the element inside of it, and extends fooType to contain more elements. By doing so, they are able to achieve an Element that contains fooElement, and two other added elements. The issue is that I'd like to add to the Element itself, not add to the element at the same level.
XSD1
<xs:schema xmlns:bas="http://www.base.com"
xmlns="https://www.adding.com"
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="https://www.adding.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="XSD2.xsd" namespace="http://www.base.com" />
<xs:complexType name="FileSpecType">
<xs:sequence>
<xs:element ref="bas:FileSpec"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="FullFileSpecType">
<xs:complexContent mixed="false">
<xs:extension base="FileSpecType">
<xs:attribute name="attributeC" type="xs:string" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="FileSpec" type="FileSpecType" />
This code ends up generating a new FileSpec
<FileSpec AttributeC="attCval" />>
<bas:FileSpec/>
</FileSpec>
What I want to achieve is more like...
<bas:FileSpec AttributeA="attAval" AttributeB="attBval" AttributeC="attCval/>
Can anybody point me in the right direction to solve my issues?
I'm thinking I could define my own dataType=FileSpec and add my own reference to external attributes, but that'd require manually copying over each attribute that exists in my original XSD2 FileSpec so I'd prefer to avoid that if possible. Then I think I could take that new FileSpec that I created and redefine the older FileSpec with it. Is this possible to do? It sounds like a lot of work that must have a simpler solution.
Its somewhat unclear what you are trying to do, if this does not cover it, please post the schema you are including as well as the XML you are trying to produce including the containing element.
You can extend an existing xs:complexType like this.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2020 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="BaseType">
<xs:attribute name="attributeA" type="xs:string" />
</xs:complexType>
<xs:complexType name="ExtendedType">
<xs:complexContent>
<xs:extension base="BaseType">
<xs:attribute name="attributeB" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="RootElm">
<xs:complexType>
<xs:sequence>
<xs:element name="BaseElm" type="BaseType" />
<xs:element name="ExtendedElm" type="ExtendedType" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
This allows you to produce XML that looks like this
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2020 (https://www.liquid-technologies.com) -->
<RootElm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BaseElm attributeA="XX" />
<ExtendedElm attributeA="YY" attributeB="ZZ" />
</RootElm>
There is another way to make use of the ExtendedType when ever its valid to use a BaseType
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2020 (https://www.liquid-technologies.com) -->
<RootElm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BaseElm xsi:type="ExtendedType" attributeB="XX" attributeA="YY" />
<ExtendedElm attributeA="XX" attributeB="YY" />
</RootElm>
Notice the xsi:type="ExtendedType" in the BaseElm, this tells the XML processor that this element actually contains data for the ExtendedType.
I have a XML schema that defines an element that may be either base64 text or an xop:Include element. Currently, this is defined as a base64Binary type:
<xs:element name="PackageBinary" type="xs:base64Binary" minOccurs="1" maxOccurs="1"/>
When I insert the xop:Include element instead, it looks like this:
<PackageBinary>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="http://google.com/data.bin" />
</PackageBinary>
But this gives an XML validation error (I'm using .NET validator):
The element 'mds:xml-schema:soap11:PackageBinary' cannot contain child
element 'http://www.w3.org/2004/08/xop/include:Include' because the
parent element's content model is text only.
This makes sense because it's not base64 content, but I thought this was common practice...? Is there any way to support this in the schema? (We have existing product that supports this syntax but we are adding validation now.)
The best I could come up with was to create a complex type that allowed any tags but was also tagged as "mixed" so it allowed text. This doesn't explicitly declare the content as base64, but it does let it pass validation.
<xs:complexType name="PackageBinaryInner" mixed="true">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:element name="PackageBinary" type="PackageBinaryInner" minOccurs="1" maxOccurs="1"/>
The solution I've found is like this:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://example.org"
elementFormDefault="qualified"
xmlns="http://example.org"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xop="http://www.w3.org/2004/08/xop/include">
<xs:import namespace="http://www.w3.org/2004/08/xop/include"
schemaLocation="http://www.w3.org/2004/08/xop/include"/>
<xs:complexType name="PackageBinary" mixed="true">
<xs:all>
<xs:element ref="xop:Include"/>
</xs:all>
</xs:complexType>
I saw this in an xml document that appeared to allow validation - basically the attribute xmlns:xop="..." did the trick:
<SomeElement xmlns:xop="http://www.w3.org/2004/08/xop/include/" id="465390" type="html">
<SomeElementSummaryURL>https://file.someurl.com/SomeImage.html</SomeElementSummaryURL>
<xop:Include href="cid:1111111#someurl.com"/>
</SomeElement >
I'm writing down some XSD file for webservice communication between an application and sharepoint.. I'm trying to make my parameters "REQUIRED" but even if i put minOccurs to 1, they could be not specified..
How can i resolve this problem? Here's one of mine XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="RemoveGroup"
targetNamespace="http://tempuri.org/RemoveGroup.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/RemoveGroup.xsd"
xmlns:mstns="http://tempuri.org/RemoveGroup.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="RemoveGroup">
<xs:complexType>
<xs:sequence>
<xs:element name="tt_group_id" type="xs:long" />
<xs:element name="tt_network_id" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I hope there's a way not to write down houndred of "if (input.Parameter != null)" ...
Using minOccurs="1" at either the <element/> or <sequence/> level is the correct thing to do. What specific error are you getting?
UPDATE
Actually within a <sequence/> parsers should expect exactly one instance of an element
UPDATE
Your parser may be emitting errors as events which you need to handle in order to capture the errors - many common parsers have this behaviour.
Something which could cause an error is a null value in the long simple type - this type does not allow blanks. If you want to indicate that nulls are allowed you should use nil=true from namespace http://www.w3.org/2001/XMLSchema-instance.
I have the following in a schema:
<xs:element name="td">
<xs:complexType>
<xs:complexContent>
<xs:extension base="cell.type"/>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:complexType name="cell.type" mixed="true">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element ref="p"/>
</xs:sequence>
</xs:complexType>
Some parsers allow PCDATA directly in the element, while others don't. There's something in the XSD recommendation (3.4.2) that says when a complex type has complex content, and neither has a mixed attribute, the effective mixed is false. That means the only way mixed content could be in effect is if the extension of cell.type causes the mixed="true" to be inherited.
Could someone more familiar with schemas comment on the correct interpretation?
(BTW: if I had control of the schema I would move the mixed="true" to the element definition, but that's not my call.)
Anyone reading my question might want to read this thread also (by Damien). It seems my answer isn't entirely right: parsers/validators don't handle mixed attribute declarations on base/derived elements the same way.
Concerning extended complex types, sub-section 1.4.3.2.2.1 of section 3.4.6 in part 1 of W3C's XML Schema specification says that
Both [derived and base] {content type}s must be mixed or both must be element-only.
So yes, it is inherited (or more like you cannot overwrite it—same thing in the end).
Basically, what you've described is the desired (and as far as I'm concerned) the most logical behavior.
I've created a simple schema to run a little test with Eclipse's XML tools.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="c">
<xs:complexType>
<xs:complexContent mixed="false">
<xs:extension base="a"/>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:complexType name="a" mixed="true">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="b"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
The above schema is valid, in the sense that not Eclipse's nor W3C's "official" XML Schema validator notices any issues with it.
The following XML passes validation against the aforementioned schema.
<?xml version="1.0" encoding="UTF-8"?>
<c xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
x
<b/>
y
</c>
So basically you cannot overwrite the mixedness of a complex base type. To support this statement further, try and swap the base and dervied types' mixedness. In that case the XML fails to validate, because the derived type won't be mixed as it (yet again) cannot overwrite the base's mixedness.
You've also said that
Some parsers allow PCDATA directly in the element, while others don't
It couldn't hurt to clarify which parsers are you talking about. A good parser shouldn't fail when it encounters mixed content. A validating parser, given the proper schema, will fail if it encounters mixed content when the schema does not allow it.
I am trying to write a xsd document that validates the following xml snippet.
<parentElement>
<someElement name="somethingRequired"/>
<someElement name="somethingElseRequired"/>
<someElement name="anything"/>
</parentElement>
It shall validate, if parentElement contains at least two occurences of someElement where one has an attribute name containing the value "somethingRequired" and the other has an attribute name containing the value "somethingElseRequired".
Is that possible?
Is that possible?
It depends on how specific your restrictions need to be. If it is good enough that all of the name attributes have unique values, then you can achieve this with <xs:unique>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="parentElement">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="2" maxOccurs="unbounded" name="someElement">
<xs:complexType>
<xs:attribute name="name" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="uniqueName">
<xs:selector xpath="someElement" />
<xs:field xpath="#name" />
</xs:unique>
</xs:element>
</xs:schema>
You can also restrict the attribute values for example to some enumerated set of allowed values instead of just using type="xs:string". It is not possible though to restrict only the first two name attributes to be unique because the xpath attribute is not allowed to contain predicates.
If you need the first name attribute to have some specific value, the second one some other specific value and the rest to have any value, then I would say that this either violates the Schema Component Constraint Element Declarations Consistent or would need some sort of co-occurrence constraint that is more specific than <xs:unique> so generally it wouldn't be possible. You might be able to make it possible by using xsi:type attribute in the instance document to explicitly declare the type of the element.
Everything you want to do is possible except for validating based on the attribute values.