What does complex content with mixed="true" allow in XML Schema? - xsd

I have the following definitions in the XML Schema:
<xsd:complexType name="ExpressionType" abstract="true"/>
<xsd:complexType name="PropertyNameType">
<xsd:complexContent mixed="true">
<xsd:extension base="ogc:ExpressionType"/>
</xsd:complexContent>
</xsd:complexType>
What does the PropertyNameType actually allow as content? Just textual content or is there more to it?
PropertyNameType is a complex type with complex content and mixed="true", extending another empty abstract complex type. That's all. My question is, which content it may have.
It may clearly have textual content (because of mixed="true"). But is something else allowed? Or is there some extension method which would put more stuff in, something with substitution groups perhaps?

To answer your question: No, only textual content is allowed.
So if the element test is defined as:
<xs:element name="test" type="PropertyNameType" />
Then the only valid content is:
<test>Hello World!</test>
No attributes, no child elements.

Related

XML Schema within a schema

The question in short - "can I define a schema within a schema which can be validated as a whole?
Explanation:
Is it possible to define a schema for the following XML. I need to define a schema for "customer". The "customertype" child element itself is a schema. Within the customertype I should have an element called "Source" which is mandatory.
<customer>
<customername>acustomer</customername>
<customertype>
<xs:schema>
<xs:element name="profession">
<xs:complexType>
<xs:sequence>
<xs:element name="Source" type="xs:int" />
<xs:element name="ProfessionName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</customertype>
</customer>
Is it possible to Define the schema for this xml so that all the requirements are met?
As Mimo has pointed out, there's no problem defining customertype (or another other element) as containing elements in the XSD namespace, which is what you appear to be asking about.
But if your goal is to be able to validate customer elements (or profession elements, which is what the schema in your example declares), it's hard to imagine a validation architecture in which that's the best way (or even a workable way) to go about it. One reason is that validating a document instance against schema information provided by the instance being validated doesn't produce the same confidence in the data's cleanliness as validating it against a known schema. (Put yourself in the shoes of an adversary seeking to subvert your validation and persuade your system to accept bogus data as valid. If the adversary gets to specify what counts as a valid document instance, how useful is it to know that the document is valid?)
What is it that prevents you from writing a schema and using it in the usual way?
[Addition, 15 October 2012, after OP's comment]
If I've understood your comment of earlier today correctly, your requirement is to allow people other than you to specify the type of the customer element however they like, subject to the proviso that that type must contain a child element named Source, whose type will be xsd:int. You don't specify whether you need access to the type definition they are using or not, so I'll try to consider both the case where you do need it and the case where you don't need it.
Three ways to make this situation work are described below. They have in common that there is
a 'main' schema document that defines a basic version of the schema, and
one or more 'auxiliary' schema documents for use in different situations.
In general, you may find it helpful to find a good textbook on XSD and review what it says about creating a schema from declarations in several schema documents.
(1) One approach uses xsi:type. You define a main schema document in which the customer element has a named type; I'll assume the type is named Customer. The Customer type accepts any element whose first child element is named Source. For example:
<xs:element name="customer" type="Customer"/>
<xs:complexType name="Customer">
<xs:sequence>
<xs:element name="Source" type="xs:int"/>
<xs:any minOccurs="0"
maxOccurs="unbounded"
processContents="lax"/>
</xs:sequence>
<xs:anyAttribute processContents="lax"/>
</xs:complexType>
Those who want a more specific type for the customer element (I'll call them the 'users') provide auxiliary schema documents for your target namespace in which they declare other complex types which restrict Customer. For example, they might want the customer element to contain elements called name, address, and phone number:
<xs:complexType name="Customer-for-us">
<xs:complexContent>
<xs:restriction base="Customer">
<xs:sequence>
<xs:element name="Source" type="xs:int"/>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="phone"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
This is a legal restriction of the Customer type, so the customer element can use it. A document instance might therefore contain an element like:
<customer xsi:type="Customer-for-us">
<Source>83760273</Source>
<name>Willy Wonka</name>
<address> ... </address>
<phone> ... </phone>
</customer>
The document is validated against the schema constructed from their auxiliary schema document, together with the main schema document, so the definition of type Customer-for-us is enforced in the usual way.
By using wildcards and lax validation, the Customer type ensures that users can do anything they like in their version of the type, as long as the first child is named Source and has type int.
(2) A second approach uses a hole in the main schema document.
You write a main schema document as before, including the declaration of the customer element as having type Customer. But the main schema document does not contain a declaration for that type. Instead, you declare the Customer type in an auxiliary schema document, which is combined with the main one at validation time in the usual way (I'd recommend you have a third schema document which serves as a driver and includes the other two, but there are many ways to make it work).
The users who want a more specific Customer type, meanwhile, write their own declaration for the Customer type, subject to the compatibility constraints about the first child named Source and so on. The users use their own driver file, which embeds the main schema document and their version of the auxiliary schema document with their own declaration of the Customer type.
This way, the xsi:type attribute does not need to be used.
(3) A third approach uses the xs:redefine or (in XSD 1.1) the xs:override facility.
You write the main schema document as described in solution (1). The users use xs:redefine or xs:override to redefine Customer as they wish. This answer is already rather long, so I do not propose to include a tutorial on the use of either redefine or override.
It is possible to create a schema importing and using another schema. This defines your customer element with customertype containing a schema:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://xml.netbeans.org/schema/Notes"
xmlns:tns="http://xml.netbeans.org/schema/Notes"
elementFormDefault="qualified">
<xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>
<xsd:element name="customer">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="customername" type="xsd:string"/>
<xsd:element name="customertype">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="xsd:schema"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The problem is that you have an additional condition on the customertype schema - so you should in theory get the standard XSD schema and modify it, but there are many different ways to satisfy that condition in a schema definition, so it is very tricky (and maybe impossible) to do this 'modification'
Probably a better approach is restrict the possible schemas used inside customertype (e.g. it must be a single element definition with complex type specified directly etc. etc) and write a sub-set of the XSD schema that describe this restricted schema definition.

Referencing an element without including/importing the schemaLocation in which it is defined

I have two xsd files. 1st file is common.xsd and the other is node.xsd. Both node.xsd and common.xsd share the same targetNamespace. common.xsd references an element defined in node.xsd using ref attribute. However, node.xsd is NOT included in common.xsd either using include or import. But the XML that I validate using these xsd files, passes the validation (Tried all corner usecases).
I wonder how this is possible. Is this because, they share the same namespace? Also is referencing an element without including/importing legal in XSD?
EDIT:
Simplified Code Snippets(The actual xsd's are much more complex and they are written in this format for bigger reason):
common.xsd
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:my="my-namespace"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
targetNamespace="my-namespace"
elementFormDefault="qualified">
<xsd:element name="common" type="my:commonType" />
<xsd:complexType name="commonType">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="my:node"/>
<!-- few other elements -->
</xsd:choice>
</xsd:complexType>
</xsd:schema>
node.xsd
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:my="my-namespace"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
targetNamespace="my-namespace"
elementFormDefault="qualified">
<xsd:include schemaLocation=common.xsd"/>
<xsd:element name="node" type="my:nodeType"
substitutionGroup="my:common" />
<xsd:complexType name="nodeType">
<xsd:complexContent>
<xsd:extension base="my:commonType">
<!-- some 5-7 attributes -->
<xsd:anyAttribute/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
These xsd's let me nest element within itself any number of times.
E.g
<my:node>
<my:node />
<my:node>
<my:node />
</my:node>
</my:node>
You can observe that my:node is referenced in common.xsd without including node.xsd. (Curious as to how this even works.)
I can make this look even more wicked... You can remove the xsd:include in node.xsd and still validate your XML! Take a look at this Xerces API for how you could do it.
The idea is that from a spec perspective, an XML Schema processor can resolve schema locations in many ways. It also means that some XSD files when looked at individually may not be valid due to dangling references, yet when put together through APIs like the one above, or custom resolvers (e.g. supporting "catalog" files) the result is an equivalent schema that is valid.
The way an XSD processor typically works, is that it puts together all the schema components that can be loaded through the references it can resolve, then it looks at the result as a whole, irrespective of where these components come from. In your case, node.xsd brings in common.xsd; the result is a valid schema, since all that is needed for components in common.xsd can be found among components already brought in by node.xsd.
In your case it is as if the inner content of the xsd:schema tag in common.xsd replaces the xsd:include in node.xsd. If you do that by hand, the result is correct, right?
As I side note, I would point out that the snippets you've shown don't illustrate the use of the common substitution group. As a reminder, you have to reference the head of the substitution group if you want you to get substitution going.

XSD annotation and documentation elements, and how to use them

We are creating xml files that we want to be compliant with the following xsd: http://www.topografix.com/gpx/1/1/gpx.xsd This xsd supports '...extending by adding your own elements here ...', see the extensionsType, which I have copied below for convenience.
1) I don't understand whether annotation and documentation are literal element names that would appear in compliant xml. I believe they are not but need confirmation. I'm assuming then that a compliant document would simply have any number of our own custom elements anywhere inside of any [extensions] element, correct?
2) Why are there two pairs of annotation/documentation elements below, with one in a sequence?
<xsd:complexType name="extensionsType">
<xsd:annotation>
<xsd:documentation>
You can add extend GPX by adding your own elements from another schema here.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
You can add extend GPX by adding your own elements from another schema here.
</xsd:documentation>
</xsd:annotation>
</xsd:any>
</xsd:sequence>
</xsd:complexType>
1) From the XML Schema specification: "Annotations provide for human- and machine-targeted annotations of schema components." Schema authors use xsd:documentation as, say Java or .NET, developers use comments.
Annotations are XML Schema artifacts; they are not to show up in an XML document. And yes, your extensions elements should go under <extensions/>; you may use any namespace, other than http://www.topografix.com/GPX/1/1
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1" creator="creator1" xmlns="http://www.topografix.com/GPX/1/1">
<extensions>
<my:element xmlns:my="urn:tempuri-org:some">Hello!</my:element>
</extensions>
</gpx>
2) Hard to say why there are two with the same comment; the difference though is that one documents the complex type, while the other the xsd:any element. I would personally have used different comments, first to explain what the complex type is for, the second just as shown.

What XML Namespace should be used when a complex type is reference by another schema in a different namespace?

Lets say I have one schema that defines a complex type named "MyType" in the namespace "general"
Then in another schema, that complex type is used.
For instance:
<xsd:schema targetNamespace="http://www.example.com/otherschema"
xmlns:general="http://www.example.com/genschema">
<xsd:import namespace="http://www.example.com/genschema" schemaLocation="general.xsd" />
<xsd:element ref="general:Mytype" />
<xsd:element name="myName" type="general:MyType" />
Should the namespace on the XML element in the XML document that conforms to this schema use the targetNamespace of otherschema or genschema.
<general:MyType />
or
<targetNamespacePrefix:Mytype />
I am asking this question because I used Axis2 to generate the java code to interact with a web service. The Axis2 code has checks against the namespace and in the example above it would check that the namespace was the general one and throw an exception if it wasn't. Of course the web service response xml used the targetNamespace instead of the general namespace so it breaks every time. I have much more faith in the Axis2 developers than the developers of the web service, but I want to make sure I am write before filing a bug report.
Your use of MyType in the "other" schema is correct: declare the namespace, use import and use the declared prefix (general).
<xsd:schema targetNamespace="http://www.example.com/otherschema"
xmlns:general="http://www.example.com/genschema">
<xsd:import namespace="http://www.example.com/genschema" schemaLocation="general.xsd" />
<xsd:element name="myName" type="general:MyType" />
</xsd>
Notice that I made your http://... items explicit to be clear which ones are typically different in the situation you describe.
If you're asking about the schema where MyType is defined, use an unprefixed name for the definition in that schema:
<xsd:schema targetNamespace="http://www.example.com/genschema"
<xsd:complexType name="MyType"> ... </xsd:complexType>
</xsd:schema>
Update based on your edit:
In the XML instance document, use of myName would have a namespace of the "otherschema" which is targetNamespace above. Use of MyType would use the "genschema" namespace.
I removed the <xsd:element ref="general:MyType"/> which only makes sense if MyType is a element (not a type) and if it's inside a type definition. Suppose "otherschema" contains:
<xsd:complexType name="otherType>
...
<xsd:element ref="general:MyElement"/>
</xsd:complexType>
In that case, MyElement would still use the "genschema" namespace in the XML instance document.
Bottom line: importing items does not change their namespace. Including them, however, does change the namespace (that is, using <xsd:include>.

How to specify read only text or label in an XML data schema

I am referring to XML data schema as detailed here: http://www.w3schools.com/schema/default.asp.
When I retrieve data from the database and submit it to the client, there are text fields which I wish to retain as uneditable display/read only fields.
For example, hypothetically in the following sequence,
<xsd:element ....
<xsd:element name="employeeName" xsd:type="xsd:string"/>
<xsd:element name="projID" xsd:type="xsd:string" readOnly='true'>
<xsd:element name="hireDate" type="xsd:date"/>
<xsd:element ....
<xsd:element name="today" type="xsd:date" readOnly='true'/>
<xsd:element ....
Where the client display would interpret the xsd stream and construct the input form.
Of course, the label is faux schema tag to illustrate my need of placing a read-only field in the midst of the form.
In the above example, projID and today should be presented to the user as read-only fields, but there is no such schema syntax as readOnly.
One way I know how to achieve this is to break the stream into two complex type segments and so split it into two input forms and get the client to present an intervening label in between the two forms.
However, that is problematic because
I have quite a few read-only info
fields that need to be presented
thro the ui. There would be too many
interruptions to a smooth single
form. It's best to have just one input form.
Some read-only fields are
presented in the middle of an entity
sequence. That means interrupting
the database-to-jdo(or
jpa)-to-client data flow for that entity.
Therefore, how to specify a read-only field element in an xml schema?
... and (sheepishly) may I ask, how to specify a hidden field?
You may use XML Schema annotations to provide such information for your application. It's awkward, but it could work.
Something along the lines of:
<xs:element name="heading" type="xs:string">
<xs:annotation>
<xs:appinfo>
<readOnly>true</readOnly>
</xs:appinfo>
</xs:annotation>
</xs:element>

Resources