UNC-Libraries / jquery.xmleditor

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

xsd2json: Problem with multiple XML Schema namespace prefixes #66

Closed vog closed 7 years ago

vog commented 7 years ago

The following valid XML schema:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xs2="http://www.w3.org/2001/XMLSchema" xmlns:foo="http://example.com/foo" targetNamespace="http://example.com/foo" elementFormDefault="qualified">
  <xs:element name="Foo" type="xs:string"/>
</xs:schema>

produces the following error message:

Error: Could not resolve reference to type 3:string from definition Foo

Here, namespace 3 is mapped to http://www.w3.org/2001/XMLSchema. It seems that xsd2json does not recognize xs:string as internal XML Schema type.

A similar situation occurs if the second namespace definition maps the default namespace, i.e. xmlns:xs2="http://www.w3.org/2001/XMLSchema" is replaced with xmlns="http://www.w3.org/2001/XMLSchema".

Workarounds:

  1. Use the second namespace prefix instead of the first:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xs2="http://www.w3.org/2001/XMLSchema" xmlns:foo="http://example.com/foo" targetNamespace="http://example.com/foo" elementFormDefault="qualified">
  <xs:element name="Foo" type="xs2:string"/>
</xs:schema>
  1. Omit the second namespace prefix:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:foo="http://example.com/foo" targetNamespace="http://example.com/foo" elementFormDefault="qualified">
  <xs:element name="Foo" type="xs:string"/>
</xs:schema>
vog commented 7 years ago

First analysis:

The main issue is the xsPrefix property in class SchemaProcessor. That one is supposed to contain "the one" XSD namespace prefix. Fortunately, it is only really used in two methods:

I propose to get rid of xsPrefix.

This is straight forward in getBuiltInType(): Just split the QName type into prefix and localname, lookup the prefix in this.localNamespaces and compare with this.xsdManager.xsNS. In other words, handle the QName the same way as extractName() does, perhaps moving common code into a third method.

However, I'm not sure about build_list(). It seems to me that the following line:

definition.type = this.xsPrefix + "string";

is a bug and that this.xsPrefix should be removed there anyway:

definition.type = "string";

@bbpennel What do you think?

bbpennel commented 7 years ago

@vog I think I agree with your analysis, we should be able to remove this.xsPrefix, it appears to be a redundant shortcut. And I agree that the usage in build_list() appears to be a bug. Do you wish to make a pull request for this?

vog commented 7 years ago

I'll provide a pull request, as I did for the other issues. I just wanted to assure myself that I'm on the right track.