The default for minOccurs property of an <element> in an XSD file is 1 (source).
Consider you have an XSD specifying a complex type containing 2 elements: <el1> and <el2>.
If you provide an XDocument only containing <el2>, the XDocument will not validate.
Instead you'll get the message:
The element Message in namespace ___ has invalid child element el2 in namespace ___.
List of possible elements expected: el1
This basically is an error on <el2> where one would expect an error on the complex type for not containing <el1>.
My question is:
Is there a way to check if all <element>-tags which have minOccurs > 0 are present?
I would say this is a very basic check when validating XML with an XSD.
Depending on the way you defined your schema, the order of appearance of elements will matter.
In this case the validator is expecting a <el1> but is seeing the element <el2> so the error is that <el2> is appearing where it should not. I belive that means you used a "sequence" when defining your complex type. So the error you at getting is correct.
If this still bothers you, and the order of the elements does not matter to your parsing use "all" instead of "sequence" which will not enforce order. The validator should then prompt you that a required element <el1> is missing. It should look something like the following:
<xsd:complexType name="MyType">
<xsd:all>
<xsd:element name="el1" minOccurs="1"/>
<xsd:element name="el2" minOccurs="1"/>
</xsd:all>
</xsd:complexType>
I hope this helps.
Related
For elements with multiplicity > 1 (i.e.. where maxOccurs>1 or maxOccurs=unbound), e.g.:
<element name="Name" type="tns:Type" minOccurs="0" maxOccurs="unbound"/>
JAXB generates the following code:
#XmlElement(name = "Name")
protected List<type> name;
Strictly speaking the above schema describes an XML snippet that looks like so:
<Name attr1="a" attr2="x">
<Name attr1="b" attr2="y">
<Name attr1="c" attr2="z">
i.e. a sequence of "Name" elements (and only that!).
When marshalling a Java object to XML the JAXB runtime creates XML, which contains an additional wrapper element around the list, like so:
<Name>
<Name attr1="a" attr2="x">
<Name attr1="b" attr2="y">
<Name attr1="c" attr2="z">
<Name>
By default the wrapping element has the same name as the individual items. Note, that there is no Java class representing that element!
One can overrule the naming to something that makes more sense by manually (!) adding a java-annotation "#XmlElementWrapper" annotation, like so:
#XmlElementWrapper(name = "NameList")
#XmlElement(name = "Name")
protected List<Type> name;
which then yields the following XML:
<NameList>
<Name attr1="a" attr2="x">
<Name attr1="b" attr2="y">
<Name attr1="c" attr2="z">
<NameList>
I agree that such a wrapper element is syntactically nice and makes the XML more readable, BUT there is a severe problem with this: the generated Java code (with or without renaming the wrapper element) generates and expects an XML dialect which - strictly speaking - does not match the original schema anymore! There is no mentioning or any implicit notion of any such wrapper element in the original schema!
The issue only surfaces, if one uses the original schema in different tools (e.g. to create web forms or a different schema-based code generator) and if their result then adheres and/or expects the original XML (i.e. the bare sequence without any wrapper element), while the JAXB-generated code creates and insists on the presence of the wrapper element. Then the two cannot understand each other!
My question thus: how can one instruct JAXB to NOT add/expect said wrapper element while marshalling/unmarshalling XML?
I have searched the web now for quite a while for solutions or work-arounds to this but found nothing! I can't imagine that nobody else before ever stumbled over this and that there seems no other solution to this other problem than to hand-tweak the XML marshalling/unmarshalling code. Any ideas or suggestions to solve this issue?
I implemented a working web service using CXF (2.7.1) with a WSDL & XSD that include, among other things, the following type:
<xs:simpleType name="SimpleIdType">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Za-z0-9:\.\-]{20}"/>
</xs:restriction>
</xs:simpleType>
I interpret this to be: Accept only 20 character strings which only contain alphanumeric characaters and ':', '.' and '-'.
When I send a SOAP message to my web service with the corresponding element containing FAAAAAAAAAAAAAAAAAAA, the service of course accepts properly without any error.
However, if I send an identical SOAP message with the # instead of F (i.e. #AAAAAAAAAAAAAAAAAAA), the service still accepts the message, without issuing any validation error (unmarshalling or otherwise).
Why?
Isn't the default ValidationEventHandler supposed to handle that by throwing an "Unmarshalling Error"?
The JAXB model (generated or hand coded) does not contain all the metadata from the XML schema in its annotations. If you want to validate against all aspects of the schema you can enable this be specifying an instance of Schema on the Unmarshaller.
http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html
I finally found the correct answer for this CXF-based case.
CXF already has runtime schema validation built-in. It is named schema validation via configuration and the only thing that was missing in my code was the XML to enable it, inside the already existing <jaxws:endpoint element in beans.xml AKA application-context.xml:
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
This discovery was made possible thanks to the answer by #Patrick.
I have nillable decimal element defined in xsd schema like this:
<xs:element name="myDecimalValue" nillable="true" type="xs:decimal" />
This is distinguished field and I want to check if it is nill in expression shape. I could use xpath() function like this:
xpath("string(//*[local-name()='myDecimalValue']/#*[local-name()='nil'])") == "true"
But it looks a little bit complicated for simple null-checking. So I'm wondering if I'm missing something and there is better way to do it?
you can try to use a decide shape instead of the xpath
your decide shape will lok like this
just ask if myDecimalValue is null
msgName.myDecimalValue != null here
than you can continue your logic
if you using a distinguished field use it its more readable for other dev
EDIT:
can you try
varString = System.Convert.ToString(msgName.myDecimalValue);
and then ask if varString is null or not
i tried it and it compile well
hopes it help
:)
I have a suspicion that this can't be achieved.
Specifically, from http://support.microsoft.com/kb/942250
Properties that have a null value are not permitted in the message
context. Therefore, if a null value is written into the message
context, this value will be deleted.
(this is in the document section relating to Promoted and Distinguished properties, so I am assuming it is applicable to both).
So it looks like your xpath solution might be the required solution, as the distinguished property won't be in the message context anyway.
I'm having trouble generating an identity constraint due to a field evaluating to a node-set within my instances.
Given a sample set of XML:
<data>
<Clusters>
<Cluster FileID="0" Function="1">
<Isotopes>
<Isotope StickID="0"/>
<Isotope StickID="1"/>
</Isotopes>
</Cluster>
<Cluster FileID="0" Function="2">
<Isotopes>
<Isotope StickID="2"/>
</Isotopes>
</Cluster>
</Clusters>
</data>
I'm trying to create a constraint such that for a given Isotope element, the each combination of #StickID combined with the #FileID and #Function of the grandparent Cluster must form a unique key.
If from the data context, I define the selector on the Cluster as so:
<xs:key name="ClusterStickRefIdentity">
<xs:selector xpath="Clusters"/>
<xs:field xpath="Cluster/Isotopes/Isotope/#StickID"/>
<xs:field xpath="#Function"/>
<xs:field xpath="#FileID"/>
</xs:key>
As expected, an error is generated when validating the instance saying the first field evaluates to a node-set with more than one member as an Isotopes element can contain an unbounded number of Isotope elements.
I'm under the impression that fields can only be applied to child contexts, which means I can't define my selector to any node deeper than Cluster, or can I? Is it possible to build the constraint I'm looking for?
I'm using JAXB 2.1.10 from Sun's JDK 1.6.0_18:
D:\apps\jdk160_18\bin>xjc.exe -version
xjc version "JAXB 2.1.10 in JDK 6"
JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build JAXB 2.1.10 in JDK 6)
I need to have JAXB's marshaller produce an empty element (e.g. <someStringField></someStringField> or <someStringField/>) when the JAXB object has the value of the empty string (""). However, rather than doing that, JAXB omits the element altogether from its output (as if it where an optional element).
My searches in the Internet indicated that JAXB should normally create this tag, as long as you set the field to the non-null empty string (i.e. myJAXBObject.setSomeStringField(""); ):
How to instantiate an empty element with JAXB
https://jaxb.dev.java.net/tutorial/section_2_2_12_8-No-Value.html#No%20Value
In my XSD, I've tried to indicate (in every way I know) that the element's presence is mandatory even if it is empty:
<xs:element name="outerElement">
<xs:complexType>
<xs:sequence>
<xs:element name="someStringField" type="xs:string" nillable="false" minOccurs="1" />
<xs:element name="someOtherStringField" type="xs:string" />
The generated code looks like this (it's the same for both elements):
#XmlElement(name = "someStringField", required = true)
protected String someStringField;
#XmlElement(name = "someOtherStringField", required = true)
protected String someOtherStringField;
However, when I marshal the following object...
outerElement.setSomeStringField("");
outerElement.setSomeOtherStringField("Value was set");
I get:
<outerElement>
<someOtherStringField>Value was set</someOtherStringField>
</outerElement>
When I was expecting:
<outerElement>
<someStringField></someStringField>
<someOtherStringField>Value was set</someOtherStringField>
</outerElement>
Or:
<outerElement>
<someStringField/>
<someOtherStringField>Value was set</someOtherStringField>
</outerElement>
Can anyone spot what I'm doing wrong?
Thank you for bringing this issue (https://bugs.eclipse.org/319028) to our attention. The bug has been fixed and will be included in the EclipseLink 2.1.1 maintenance release. If you want access to this fix earlier you can pick up the nightly download starting July 8th from:
http://www.eclipse.org/eclipselink/downloads/nightly.php
Apologies. I THOUGHT I was using JAXB from Sun's JDK, but I wasn't. There was a left-over jaxb.properties in my classes/ folder that was created by JDeveloper when I generated the bindings. I was actually using JAXB2.0 from EclipseLink/MOXy.
Removing the properties file allowed JAXB2.1 to be used and fixed my issue.