Given the following schema
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://tempuri.org/foo"
elementFormDefault="qualified">
<xs:element name="foo" type="xs:string" />
</xs:schema>
Is the following XML valid?
<foo xmlns="http://tempuri.org/foo" xml:lang="en-US">test</foo>
That is, is the "xml:lang" attribute allowed here?
The reason for this question is that WCF (Windows Communication Foundation) endpoints configured to use SOAP/1.1 over HTTP (basicHttpBinding in WCF terms) always includes the "xml:lang" attribute on the "faultstring" element when a fault is raised. According to the SOAP/1.1 envelope schema this element is of the simple type "xs:string".
I wouldn't really care if it wasn't for a customer ours is having problems deserializing these faults. I have reported this as a potential bug to Microsoft but got the response that this is by design and that it is conformant to SOAP/1.1. Reading XML Schema specifications leads me to believe that Microsoft is wrong and that no attributes are allowed on elements of simple types.
Am I missing something here related to attributes in the "xml:" namespace?
What I really would like to have is some sort of "official" definition that allows me to say "you're wrong" to Microsoft or "you have a buggy WS stack" to our customer without making a fool of myself.
EDIT: The answer to the title question seems to be "no" as stated below. The resolution to my WCF problem turned out to be pretty simple as well. Pass the empty string as the xmlLang parameter in the constructor of the System.ServiceModel.FaultReasonText and the attribute won't be added. Passing null doesn't work (ArgumentNullException) and neither does the one argument constructor (the system default language will be set as xml:lang)
According to XML Schema, O'reilly, from Eric van der Vlist, p. 170 (XML Attributes), the xml:lang attribute need to be declared in schema, with declared xml namespace and import a schema for xml namespâces.
Related
I'm creating an XML schema definition that extends an existing XSD (which was generated from a model built in Enterprise Architect) - I'm not permitted to modify the text of the existing XSD for copyright reasons, but I can reference it. The core aim is to be able to create elements from the original schema but add new sub-elements to them (the new sub-elements will be defined in a new namespace).
I've done what I needed to do by hand-crafting a new XSD based on the solution from How to extend a complex type in a different namespace without changing name which uses xs:import and xs:redefine to refer to and extend the original schema - so far so good! For completeness, the solution required two XSDs to define the new elements and then redefine the old namespace.
new.xsd:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns="new-namespace"
xmlns:bs="old-namespace"
targetNamespace="new-namespace">
<xs:import namespace="old-namespace" schemaLocation="old.xsd"/>
<xs:element name="myElement" type="bs:OldCustomType" />
</xs:schema>
and main.xsd (which is the definition file you can reference to validate XML etc.):
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns="old-namespace"
targetNamespace="old-namespace"
xmlns:new="new-namespace">
<xs:import schemaLocation="new.xsd" namespace="new-namespace"/>
<xs:redefine schemaLocation="old.xsd">
...
<!-- Modifications go here -->
...
</xs:redefine>
</xs:schema>
However I now need to similarly extend the original schema's WADL, also generated from the EA model. It would also be preferable to have an EA model to generate documentation etc. if possible, hence I'm trying to replicate the same schema functionality in EA. Unfortunately I'm not sure that the matching solution is possible in EA as this link indicates that the redefine XML schema construct has not been implemented in EA.
I was wondering if anyone has any alternative ways of achieving the same import-redefine type of functionality in EA (i.e. that doesn't rely on redefine)?
I've been using an XML format that is a mix of different existing formats and some custom elements and attributes, and I thought I should write a schema for those custom bits.
One thing I do is use custom attributes on elements in existing formats, like this:
<ns1:something attA="b" attB="a" ns2:extraAtt="c"/>
I understand that doing this is allowed but I cannot think how to declare my "extraAtt" in XML Schema or, worse, in a DTD.
I have tried reading the specification, but it could just as well be written in Chinese as far as I am concerned. Most tutorials talk only about "name", "type", and "use", e.g. this one and that one.
Each schema document defines components (pieces of a schema) for one namespace. So to define your attribute ns2:extraAtt you want a schema document something like this one:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/my-ns2">
<xs:attribute name="extraAtt" type="xs:anySimpleType"/>
</xs:schema>
The declaration of element ns1:something will need to allow for this attribute somehow, either with an attribute reference (<xs:attribute ref="ns2:extraAtt"/>) or with an attribute wildcard (<xs:anyAttribute namespace="http://example.com/my-ns2"/> or similar).
Sorry about the legibility of the spec; it's a long story, but essentially some members of the WG did not think people like you exist ("no one except implementors reads the spec, and as long as they don't complain it's readable enough" -- at least, that was what they said before some implementors did complain, loudly and bitterly; then they just changed the subject).
To declare just the attribute you can use this XSD:
<xs:schema
targetNamespace="theNamespaceUri"
elementFormDefault="qualified"
attributeFormDefault="qualified"
xmlns="theNamespaceUri"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:attribute name="extraAtt" type="xs:string">
</xs:attribute>
</xs:schema>
(assuming extraAtt is a simple string - you can use any type, or restrict an existing type etc.)
Where is the XSD schema definition file for the namespace "http://www.w3.org/2001/XMLSchema-instance"?
Strange it may sound, but the XML schema for http://www.w3.org/2001/XMLSchema-instance namespace does exist and is found exactly by the very URL denoted by the namespace URI:
http://www.w3.org/2001/XMLSchema-instance
For a proof, just open that link (URL) in an HTML browser (e.g. FireFox).
You will probably see some HTML text, like: "XML Schema instance namespace ...".
Then, save that 'HTML' as a file on your computer (e.g. File | Save Page As).
When you look into this file, you will see that it is not HTML at all. Rather, it is a complete XML schema for that namespace!
Equally, you can import the http://www.w3.org/2001/XMLSchema-instance namespace into your own schema as the following:
<xs:import namespace="http://www.w3.org/2001/XMLSchema-instance"
schemaLocation="http://www.w3.org/2001/XMLSchema-instance"/>
See also this question: Error while parsing xsd using xjc, which although sounds very differently, actually very much related to the same problem.
Just to add fuel to the fire -- many XML tools have knowledge of http://www.w3.org/2001/XMLSchema-instance baked-in, so it looks like you never need the schema at all. In fact, you need the schema if you are using an XML tool that does not bake-in this knowledge.
So is for that reason that we find actually always beginning of xml documents where there ins't xml-schema xsd declaration at all? For example like this:
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd">
Here is some updated information on this topic.
XSD 1.1 part 1 §2.6 states:
XML Schema Definition Language: Structures defines several attributes
for direct use in any XML documents. These attributes are in the
schema instance namespace (http://www.w3.org/2001/XMLSchema-instance)
described in The Schema Instance Namespace (xsi) (§1.3.1.2) above. All
schema processors must have appropriate attribute declarations for
these attributes built in.
Further, §3.2.6.4 says:
The {target namespace} of an attribute declaration, whether local or
top-level, must not match http://www.w3.org/2001/XMLSchema-instance
(unless it is one of the four built-in declarations given in the next
section). Note: This reinforces the special status of these
attributes, so that they not only need not be declared to be allowed
in instances, but in consequence of the rule just given must not be
declared.
So, you can't declare attributes such as xsi:type or xsi:schemaLocation in a schema document, and therefore you can't import a schema document that attempts to declare such attributes.
This of course is XSD 1.1 and therefore doesn't directly constrain an XSD 1.0 processor. However, it's one of the many areas where XSD 1.1 issues guidance for cases where XSD 1.0 said nothing, and where different implementations went off in different directions.
Is there a way in an xsd schema to require that an element have another element somewhere as a descendant?
For example, element parent requires a descendant desc. This is valid:
<parent>
<a>
<b>
<desc></desc>
</b>
</a>
</parent>
As is this:
<parent>
<c>
<desc></desc>
</c>
</parent>
but this isn't:
<a>
<parent>
<b/>
</parent>
</a>
The potential child elements for parent are many and complicates, so it would be difficult to enumerate every possible valid configuration.
Something like the key/selector schema elements seems like it would work, where I could provide an xpath expression defining the valid locations for desc element, but all of the examples I've found are aimed at matching up the value of attributes.
No, (almost) all XML Schema validation is shallow, called "local" in the spec. Here's one excerpt that emphasizes type validation as "local" validation.
Element Validated by Type If an
element information item is ·valid·
with respect to a ·type definition· as
per Element Locally Valid (Type)
(§3.3.4), [it is marked as] ·validated·.
The only exception is for the identity constraints like uniqueness and key-references which have a broad scope in an XML document but narrow uses.
I don't know if XSD supports what you are trying to do, but there is a work-around.
You could do complex validations with a two-step process:
First simply use your XSD schema for basic validation
Next use an XSLT which does more complex validations, and outputs the result of that validation
This may not plug in well to whatever framework you are working with, but might work well for (partially) custom code. It also has the advantage (over doing the extra validations in code) that you can publish both documents.
From a quick google search, one effort towards this end is Schematron. It actually foregos XSD entirely, and just uses XSLT. It appears to be a published standard:
http://www.schematron.com/
Suppose we have a stylesheet which pulls in metadata using the key() function. In other words we have instance documents like this:
<items>
<item type="some_type"/>
<item type="another_type"/>
</items>
and a table of additional data we would like to associate with items during processing:
<item-meta>
<item type="some_type" meta="foo"/>
<item type="another_type" meta="bar"/>
<item type="yet_another_type" meta="baz"/>
</item-meta>
Finally, suppose we want to do schema validation on the instance document, restricting the type attributes to the set of types which occur in item-meta. So in the schema we want to use key/keyref instead of restriction/enumeration. This is because using restriction/enumeration will require making a separate list of valid type attributes.
However, it doesn't look like key/keyref will actually work. Having tried it (with MSXML 6.0) it appears the selector of a schema key won't accept the document() function in its xpath argument, so we can't examine the item-meta data, whether it appears in an external file or in the schema file itself. It looks like the only place we can look for keys is the instance document.
So if we really don't want to have a separate list of valid types, we have to do a pre-validation transform, pulling in the item-meta stuff, then do the validation, then do our original transform. That seems overcomplicated for what ought to be a relatively straightforward use of XML schema and stylesheets.
Is there a better way?
Selectors in key/keyref allow only a very restricted xpath syntax. Short, but not completely accurate: The selector must point to a subnode of the element declared.
The full definition of the restricted syntax is -> here.
So, no I don't see a better way, sorry.
BTW: The W3C states that this restriction was made to make life easier on implementers of XML Schema processors. Keep in mind that one of the design goals of XML Schema was to make it possible to process a document in streaming mode. That explains really a lot of the sometimes seemingly random restrictions of XML Schema.
Having thought about it a little more, I came up with the idea of having the stylesheet do that part of the validation. The schema would define the item type as a plain string, and the stylesheet would emit a message and stop processing if it couldn't look up the item type in the item-meta table.
This solution fixes the original problem of having to write down the list of valid types more than once, but it introduces the problem that validation logic is now mixed in with the stylesheet logic. I don't have enough experience with XSD+XSLT to tell whether this new problem is less serious than the old one, but it seems to be more elegant than what I wrote earlier about pulling the item-meta table into each instance document in a pre-validation transform.
You wouldn't need to stop the XSLT with some error. Just let it produce something that the schema won't validate and that points to the original problem like
<error txt="Invalid-Item-Type 'invalid_type'"/>
Apart from that please keep in mind that there are no discussion threads here. The posts may go up and down, so it's better to edit your question accordingly.
Remember, the philosophy here is "One question, and the best answer wins".