I'm having the following "imp.xsd":
<xsd:schema targetNamespace="http://imported"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Imported" type="xsd:string"/>
</xsd:schema>
imported from "incl.xsd":
<xsd:schema targetNamespace="http://main"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://imported" schemaLocation="file:///C:/.../imp.xsd"/>
<xsd:element name="Included" type="xsd:string"/>
</xsd:schema>
which in turn is included from "main.xsd":
<xsd:schema targetNamespace="http://main"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="file:///C:/.../incl.xsd"/>
<xsd:complexType name="dummy">
<xsd:sequence xmlns:impt="http://imported" xmlns:incl="http://main">
<xsd:element ref="incl:Included"/>
<xsd:element ref="impt:Imported"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Question: is "main.xsd" a valid xml schema document?
When validated with the xmllint parser (or from python lxml library, which in turn uses xmllint), I get the following error:
Element '{http://www.w3.org/2001/XMLSchema}element', attribute 'ref':
References from this schema to components in the namespace
'http://imported' are not allowed, since not indicated by an import
statement. WXS schema main.xsd failed to compile
However, another (IBM) parser accepts this XSD without any complaints.
As far as I understand xsd:include, it should behave as if the whole included XSD is inlined into the main document. So, in my opinion, the "main.xsd" should be valid. Is it?
Edit: I was experimenting with xmllint a bit, and when I add the line
<xsd:import namespace="http://imported" schemaLocation="file:///C:/.../imp.xsd"/>
into "main.xsd", xmllint accepts that schema. However, when I add the same line while omitting file:///, I get the following warning:
Element '{http://www.w3.org/2001/XMLSchema}import': Skipping import of
schema located at 'C:/.../imported.xsd' for the namespace
'http://imported', since this namespace was already imported with the
schema located at 'file:///V:/.../imported.xsd'.
Hence I deduce that the original "main.xsd" is valid and that this is a bug in xmllint.
See this thread on the xmlschema-dev#w3.org mailing list. In his answer, Henry S. Thompson quotes following part of the spec:
For a ·QName· to resolve to a schema component [...] the
·namespace name· of the ·QName· is the same as one of the following:
[...]
The ·actual value· of the namespace [attribute] of some <import>
element information item contained in the <schema> element
information item of that schema document [emphasis added].
So indirect imports are not supposed to work.
Related
I have a problem generating equals and hashcode methods for my imported xsd files which are output to a separate location to my wsdl files. I currently have a .wsdl and .xsd file in the same folder. The .wsdl file imports these xsd files which have a different namespace to the wsdl file. When these xsd files are generated they do not contain equals or hashcode methods. Below is a sample of my pom/xml config and files:
<wsdlOption>
<wsdl>
src/main/xml/wsdl/Rule.wsdl
</wsdl>
<wsdlLocation>classpath:wsdl/Rule.wsdl</wsdlLocation>
<bindingFiles>
<bindingFile>src/main/xml/wsdl/bindings.xjb</bindingFile>
</bindingFiles>
<extraargs>
<extraarg>-impl</extraarg>
<extraarg>-verbose</extraarg>
<extraarg>-xjc-XsimpleEquals</extraarg>
<extraarg>-xjc-XsimpleHashCode</extraarg>
</extraargs>
</wsdlOption>
Sample wsdl (imported Rule.xsd is not generating methods):
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.ws.com/Rule/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Rule"
targetNamespace="http://www.ws.com/Rule/">
<wsdl:types>
<xsd:schema targetNamespace="http://http://www.ws.com/Rule/">
</xsd:schema>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.ws.com/Rule/"
xmlns:pref="http://www.xsd.com/Rule" xmlns:pref1="http://www.xsd.com/Common">
<xsd:import schemaLocation="Rule.xsd"
namespace="http://www.xsd.com/Rule">
</xsd:import>
<xsd:import schemaLocation="Common.xsd" namespace="http://www.xsd.com/Common"></xsd:import>
<xsd:element name="ListGrid">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="request"
type="pref:test" maxOccurs="1" minOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
I assume this is a problem with the location of the generated xsd as I can get it to work by moving this to the same parent folder as the wsdl namespace. I would like to get this to work without moving these files locations as I have a large codebase that would require a large refactor if I do this.
Any suggestions would be welcome.
I found a solution to this problem by adding the following to the pom.xml configuration:
<extraarg>-p</extraarg>
<extraarg>http://www.xsd.com/Rule=com.xsd.rule</extraarg>
Even though this does not change the namespace/package location it seems to now generate the imported files equals and hashcode methods.
I have a large .xsd file structured like this:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns="foo:bar:baz" xmlns:quux="foo:bar:baz"
quux:attr1="A" quux:attr2="5">
<xsd:attribute name="attr1" type="xsd:string"/>
<xsd:attribute name="attr2" type="xsd:int"/>
<xsd:annotation>
<xsd:documentation>
<xhtml:h1 quux:attr1="A" quux:attr2="5">
Documentation here
</xhtml:h1>
</xsd:documentation>
</xsd:annotation>
<xsd:complexType name=... />
</xsd:schema>
I get the error: "The foo:bar:baz:attr1" attribute is not declared.
Why is it not finding the attribute? It's right there. How can I make these attributes available to the documentation's header?
Future edit: the above schema got the green light from actual XML Validators. Guess there was just something Visual Studio was reading incorrectly.
The XSD you show can be imported or included into another XSD that includes an element declaration, but alone it cannot be used to validate an XML file because it does not declare even a single element.
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.
In the code snippet below, I have a question about such names as , <xsd:element ...>, <xsd:complexType ...>. Where are those names declared? I follow the URI http://www.w3.org/2001/XMLSchema -> http://www.w3.org/2001/XMLSchema.xsd, and can't find their declarations. I'm curious as to whether they're "keywords" that need to be supported by every parser. I'm new to XML and obviously lack of some basic info to understand this. Please explain. Thank you.
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
<xsd:element name="comment" type="xsd:string"/>
<xsd:complexType name="PurchaseOrderType">
As mentionned by Jukka, the XML Schema specification can be found on w3c site. See the following URL for all XML Schema recommendations http://www.w3.org/TR/#tr_XML_Schema
The URL you tried to reach ( http://www.w3.org/2001/XMLSchema ) is not supposed to be active. It's only an identifier of the XML Schema dialect, dialect that includes the element you mentionned (complexType, element...).
The xs: or xsd: before the element name is called a "prefix" and is a reference to an identifier URI that is defined by xmlns:xs="http://www.w3.org/2001/XMLSchema" or xmlns:xsd="http://www.w3.org/2001/XMLSchema". Regularly, those namespace declarations appears only in the root element.
Elements like the ones you mention are defined in the XML Schema specification, part 1.
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>.