UNC-Libraries / jquery.xmleditor

jQuery based XML editor plugin.
153 stars 71 forks source link

xsd2json: Wrong handling of namespaces #80

Closed vog closed 7 years ago

vog commented 7 years ago

Pull request #69 did not fix #67 in the correct way. The solution was too superficial. The real problem is deeper in the xsd2json code and needs to be fixed with a more thorough change.

The main problem is that the name of a definition is treated as a QName in xsd2json. But it is really just a local name that is always bound to the target namespace. This subtle difference is important, because all the real QNames (type, ref, etc.) do not care about the target namespace at all. If these have no prefix, they must be bound to whatever namespace is bound to the empty prefix (xmlns=...). Even more so, there is a special rule in XML Schema that if the empty prefix is unbound, it defaults to the XML Schema namespace, not the target namespace!

So it is wrong to ever bind targetNS to the empty prefix by any automatism. Instead, definition names need to be resolved by a separate mechanism.

To illustrate the issue, consider the following definition:

<xs:schema ... xmlns="http://example.com/bar" targetNamespace="http://example.com/foo">
  <xs:element name="Foo" type="date"/>
</xs:schema>

Here, Foo is bound to the http://example.com/foo namespace, while date is looked up in the http://example.com/bar namespace.

Moreverover, if the xmlns=... definition is left out:

<xs:schema ... targetNamespace="http://example.com/foo">
  <xs:element name="Foo" type="date"/>
</xs:schema>

then Foo is still bound to the http://example.com/foo namespace, while date is looked up in the http://www.w3.org/2001/XMLSchema namespace.

In neither case date is ever looked up in the target namespace.

vog commented 7 years ago

Just a quick addition to my statements above: These are only true for schemas where an explicit targetNamespace is set.

For schemas without namespaces, and most importantly for Chameleon Includes (see https://www.w3.org/TR/xmlschema11-1/#src-include), an absent namespace in a QName is indeed resolved to the (effective) targetNamespace. These two special cases are handled as well in pull request #81.

Still, the resolution of those QNames is completely independent from the namespace to which the definition names (as local names) are bound.