XSD Identity Constraint with a node-set - xsd

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?

Related

Mule 3 retrieving the placeholder value dynamically

I have a use-case that I need to retrieve the value from my properties file but that key should be derived dynamically from my query params.
How to handle this in MEL or Groovy? I am aware it is possible in DW.
Http request
https://localhost:9898/getStore?search=customer.weststore.name
And my placeholders are -
file.properties
customer.weststore.name=TESTING
customer.eaststore.name=IRERRER
So the way I need to access something like this
<set-variable variableName="westDetail" value="#[message.inboundProperites['customer.weststore.name']" doc:name="Variable"/>
<logger message="${westDetail}" level="INFO" /> --> Failed as no placeholder available
When I tried the above it's failing due to no placeholder as "westDetail" available whereas I need the fetch that particular key from the properties file.
This is something related to this article - https://help.mulesoft.com/s/question/0D52T00004mXTQUSA4/dynamically-read-property-values-from-a-properties-file-in-mule but the only solution provided with DW not MEL or Groovy.
How anyone advises, Is it possible?
I understand that the problem is that you want to query the properties by a key that is obtained at execution.
You are doing it incorrectly. ${} is for evaluating the value of a property, which is done at initialization time of the application. You missed that get the actual value in the set-variable.
#[] is for executing a MEL expression, which happens at execution time. flowVars.westDetail is a MEL expression that returns the value of flow variable westDetail. You can't use a MEL expression to evaluate the property placeholder ${}, because they are evaluated at different times.
A solution is to use a Spring bean to store the properties, instead of a configuration properties placeholder. Then you can assign it to a flow variable and access it like a map.
Example:
<spring:beans>
<spring:bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<spring:property name="location" value="classpath:items.properties"/>
</spring:bean>
</spring:beans>
<flow name="myFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<set-variable value="#[app.registry.myProperties]" variableName="props"></set-variable>
<logger message="a=#[flowVars.props['a']]" level="INFO"/>
</flow>
items.properties:
a=1
b=2
c=3
Output:
a=1

JAXB(2): can one suppress the unwanted list-wrapper element

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?

Why does this XSD element pass default ValidationEventHandler?

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.

BPEL issue on Open ESB com.sun.xml.transform.sware.TooManyElementsException

I am having a problem mapping nested lists in an Open ESB BEPL processes.
I am calling a service that returns a object containing a list. One of the parameters in that list is another list. My return object, that I'm mapping to, more or less replicates the structure of the object returned by the service. (I.e. it has a list, one of the parameters of which is a nested list)
I can map the parameters from the first level lists to each other without issue. When I try to map the parameters in the nested list to the nested list in my return object I get a com.sun.xml.transform.sware.TooManyElementsException. Which seems to indicate (from what I can gather) that I'm trying to map a collection into a single variable. (Almost like BPEL is not iterating through the nested list). This is all being done in the same BPEL assign.
Here is my BPEL Code:< assign name="mapGetQuotesOut" >
<!-- this works -->
<copy> <from>$getClientQuotesOut.parameters/ns0:GetClientQuotesResult/ns1:QuotePolicy/ns1:ProductID</from>
<to>$viewCustomerOut.part1/return/quotes/produsctID</to>
</copy>
<!-- this works -->
<copy>
<from>$getClientQuotesOut.parameters/ns0:GetClientQuotesResult/ns1:QuotePolicy/ns1:LeadSourceCode</from>
<to>$viewCustomerOut.part1/return/quotes/leadSourceCode</to>
</copy>
<!-- this causes the error -->
<copy>
<from>$getClientQuotesOut.parameters/ns0:GetClientQuotesResult/ns1:QuotePolicy/ns1:QuoteItems/ns1:QuoteItem/ns1:ItemDesc&lt<from>
<to>$viewCustomerOut.part1/return/quotes/vehicleQuoteItems/itemDescription</to>
</copy>
<!-- this also causes the error -->
<copy>
<from>$getClientQuotesOut.parameters/ns0:GetClientQuotesResult/ns1:QuotePolicy/ns1:QuoteItems/ns1:QuoteItem/ns1:AgentCode</from>
<to>$viewCustomerOut.part1/return/quotes/vehicleQuoteItems/agentCode<to>
</copy>
</assign>
Any ideas or suggestions?
Mike
You need to perform XSL transformation by using for-each.

How to check XML for missing elements using XSD

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.

Resources