I'm trying to convert an XSD I have no control over to Java classes using JAXB. The errors I'm getting are :
[ERROR] cvc-pattern-valid: Value 'true' is not facet-valid with respect to pattern '0|1' for type 'BooleanType'.
line 139 of http://neon/meaweb/schema/common/meta/MXMeta.xsd
[ERROR] a-props-correct.2: Invalid value constraint value '1' in attribute 'mxencrypted'.
line 139 of http://neon/meaweb/schema/common/meta/MXMeta.xsd
The code in the XSD that contains the error is in:
<xsd:complexType name="MXCryptoType">
<xsd:simpleContent>
<xsd:extension base="xsd:base64Binary">
<xsd:attribute name="changed" type="ChangeIndicatorType" use="optional" />
<xsd:attribute name="mxencrypted" type="BooleanType" use="optional" default="1" />
</xsd:extension>
</xsd:simpleContent>
Specifically it's the attribute mxencrypted using the BooleanType. BooleanType is defined as
<xsd:simpleType name="BooleanType">
<xsd:restriction base="xsd:boolean">
<xsd:pattern value="0|1" />
</xsd:restriction>
</xsd:simpleType>
From searching around this seems to be a somewhat common case. From what I can tell the default in the mxencrypted line shouldn't be a 1? When I load the XSD into Liquid XML, the schema doesn't report errors. Validating the XSD here (http://www.utilities-online.info/xsdvalidation/#.UV3zkL_EW0s) reports the same errors as JAXB.
Is there a way to tell JAXB to ignore this problem and just generate the class ignoring the default?
Your question is similar to this one (and I've just updated it with relevant information). I am not aware of a way to tell JAXB to ignore it, since this error happens in the XSD schema processor (before JAXB's xjc starts to do its work actually).
The only way may be to filter out the default attributes; however, in this case it is obvious that the XSD designer intended to have a default value of true, which would not be the case with your generated code (Java defaults to false).
This could yield unwanted fracas, my recommendation would be to work with the XSD provider to get it fixed.
Maybe a sidebar, but I personally consider the use of defaults in XSDs as an interoperability monster : any XML processor that is not relying on the XSD would behave differently than one that does.
Related
Recently, I discovered that one of our xs:enumeration types included the same value twice:
<xs:simpleType name="typ-TypeCodeRequest">
<xs:restriction base="xs:string">
<xs:enumeration value="B1"/>
<xs:enumeration value="B2"/>
<xs:enumeration value="B2"/>
<xs:enumeration value="B3"/>
<xs:enumeration value="B4"/>
<xs:enumeration value="B5"/>
</xs:restriction>
</xs:simpleType>
Now, an external partner complained about it, claiming that "that cannot ever work". This confused me somewhat, since my tries to find out wether or not duplicate entries in enumerations are allowed or not - even if pointless - were fruitless.
This was not detected as wrong by any validation, and did not result in any problems when generated into code and used with Apaches CXF framework. Are we handling this issue too lax, or is the external partner too strict?
Strictly speaking, the gist of your problem is really in clarifying the context in which one said that cannot ever work.
In terms of the XSD spec, your fragment is valid - so that person is wrong. Duplicate enumerations are annoying to read and most likely indicate a bug, due to a typo which maybe misses one of possible values... still, perfectly valid.
The XML Schema spec, in both 1.0 and 1.1 (section 4.3.5) has no restriction placed on the uniqueness of the enumerated values. It's all about It is an ·error· if any member of {value} is not in the ·value space· of {base type definition}.
Interestingly enough, both specs could've placed constraints in the "schema for schema" to ensure uniqueness... but none did.
To expand on this... It is easy to place redundant constraints; a sequence of enumerated values could also be written using regex patterns. For e.g.:
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="test" type="test"/>
<xsd:simpleType name="test">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="y"/>
<xsd:enumeration value="n"/>
<xsd:pattern value="y|n"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
In this case, the pattern has no use... yet, the XSD spec does not flag this as wrong (even though it is superfluous, since the enumeration always wins).
Maybe that person's problem is caused by some program that binds XSD to something else... and that program is creating duplicate entries, on the assumption that enumerated values should be unique (which is a wrong assumption).
If I would be you, I would simply fix the XSD; and ensure that you're using some XSD static analysis tooling to validate that it doesn't happen in your releases (even though is valid).
I would suggest that their complaint is more politically rather than technically motivated.
However, it is clearly incorrect and if you did try to convert this enum to a type in say, c#, you'd be unable to cleanly do it.
eg: won't compile:
enum Color
{
White = 0,
Black = 1,
Orange = 2,
Orange = 3
}
So if it's clearly incorrect why not create a new version of your schema?
i have XML structure as below (just part of large XML)
<Person>
<firstName>
<lastName>
<Partner>
<firstName>
...
</Person>
i need to keep additional metadata with each field for example to indicate if its updatable or not
i c two approaches
1) add the metadata at each FIELD level. i feel this overly complicates the XSD as each element is now an OBJECT
<Person>
<firstName updatable="true" ... />
...
</Person>
2) separate out the metadata as below
BUt how do i link the metadata to the data? via a uniquie name? can someone consuming the XML easily link it?
Is there a better way? Thanks!
<data>
<Person>one
<firstName>
<lastName>
<Partner>
<firstName>
...
</Person>
<Person>two
<firstName>
<lastName>
<Partner>
<firstName>
...
</Person>
</data>
<metadata>
<field name="firstName" updateble="false"/>
....
</metadata>
i think this is similar to
Add metadata to an XSD definition
but it does not have any answer
My (maybe rhetoric) question would be why would someone want to see this metadata with each XML if it is static in relationship to the model?
I'll show you a UBL XSD snippet (XML namespaces elided as irrelevant):
<xsd:element ref="cbc:UBLVersionID" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
<ccts:Component>
<ccts:ComponentType>BBIE</ccts:ComponentType>
<ccts:DictionaryEntryName>Application Response. UBL Version Identifier. Identifier</ccts:DictionaryEntryName>
<ccts:Definition>The earliest version of the UBL 2 schema for this document type that defines all of the elements that might be encountered in the current instance.</ccts:Definition>
<ccts:Cardinality>0..1</ccts:Cardinality>
<ccts:ObjectClass>Application Response</ccts:ObjectClass>
<ccts:PropertyTerm>UBL Version Identifier</ccts:PropertyTerm>
<ccts:RepresentationTerm>Identifier</ccts:RepresentationTerm>
<ccts:DataType>Identifier. Type</ccts:DataType>
<ccts:Examples>2.0.5</ccts:Examples>
</ccts:Component>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
You could see here that there's a lot of structured data which could easily pass as something related to your question. Fundamentally though, this is a mechanism that uses the XSD annotations mechanism, to achieve things in relationship to the XSD. Another one is that used by JAXB custom binding mechanism:
<xsd:simpleType name="ZipCodeType">
<xsd:annotation>
<xsd:appinfo>
<jxb:javaType name="int" parseMethod="javax.xml.bind.DatatypeConverter.parseInt" printMethod="javax.xml.bind.DatatypeConverter.printInt"/>
</xsd:appinfo>
</xsd:annotation>
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="10000"/>
<xsd:maxInclusive value="99999"/>
</xsd:restriction>
</xsd:simpleType>
While this is different than the UBL example, (documentation vs. appinfo), both are using the XSD annotation mechanism.
JAXB's custom bindings also supports a model where the custom bindings are separate from the XSD (in their own separate XML file). The correlation between the custom binding file (the metadata in your case) and the XSD (the XML in your case) is done through XPath matches.
This brings about another clarification: what is the processing model you have in mind? Dynamic (i.e. the metamodel is static, but can be applied to arbitrary XSDs)? Platform? Below is a solution that could work for what you need, in a dynamic fashion, if it happens to match your platform.
.NET:
Build an XSD the way I've referred to above (i.e. annotations of some sort).
At runtime, validate your XML against this XSD. Each node will then have the SchemaInfo property filled in. Using classes in System.Xml.Schema you could easily process the SchemaElement or SchemaAttribute in your SchemaInfo property as an XmlSchemaAnnotated class, which is what both are.
The above is basically PSVI applied to your XML. The same exists for Java (on this Xerces page search for How do I retrieve PSVI from the DOM?)...
I could picture solutions for XSLT as well, or not involving XSD at all... the above though should be sufficient to get you started.
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.
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.
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>.