Referencing specific element(s) in a RelaxNG schema with externalRef - validation

So I have one RelaxNG schema that references another:
<define name="review">
<element name="review">
<externalRef href="other.rng"/>
</element>
</define>
other.rng:
<start>
<choice>
<ref name="good"/>
<ref name="bad"/>
</choice>
</start>
<define name="good">
<element name="good"/>
</define>
<define name="bad">
<element name="bad"/>
</define>
Is there any way I can import only <good>, but not allow <bad>? The goal being:
<review><good/></review>: valid
<review><bad/></review>: invalid

The grammar you import with externalRef can't be modified. To achieve the kind of validation you're after, I see this method :
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<include href="other.rng">
<start combine="choice">
<ref name="review"/>
</start>
</include>
<define name="review">
<element name="review">
<ref name="good"/>
</element>
</define>
</grammar>
You include the other schema.
You override the start element in the include (good and bad elements won't be possible root).
The specification says :
If the include element has a start component, then all start
components are removed from the grammar element.
You make a reference to the good element in your review definition.

Related

how i can add values to my Adress endpoint in wso2 ESB/EI

i want to add values dynamically to adress endpoint in the proxy in wso2 ESB/EI
<address uri="mqtt:/SampleProxy?mqtt.server.host.name=thingsboard.cloud&mqtt.server.port=1883&mqtt.client.id=esb.test.sender&mqtt.topic.name=v1/devices/me/telemetry&mqtt.subscription.qos=0&mqtt.blocking.sender=true&mqtt.subscription.username=25416990;">
lets say for exemple i want to add "test" at the end of the endpoint how i can do this ?
For a similar problem, but with sending msg to rabbitmq, I created template, where i set exchangeName and routingKey dynamicaly. In the same manner, you can create your own template. You need to create Header named "To" and using XPATH concate interesting address endpoint, and for dynamic values you just use $func:{parameter name}
Something like below:
<?xml version="1.0" encoding="UTF-8"?>
<template xmlns="http://ws.apache.org/ns/synapse" name="rabbitmq.sender">
<parameter name="exchangeName"/>
<parameter name="routingKey"/>
<sequence>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<header name="To"
scope="default"
expression="concat('rabbitmq:/?rabbitmq.connection.factory=CachedRabbitMQConnectionFactory&rabbitmq.exchange.name=',$func:exchangeName,'&rabbitmq.queue.routing.key=',$func:routingKey)"/>
<send/>
</sequence>
</template>
To use that, call-template mediator is needed. In brackets you can put expression, like below:
<call-template target="send.rabbitmq">
<with-param name="exchangeName" value="test"/>
<with-param name="routingKey" value="{get-property('testValue')}"/>
</call-template>

How-to include an optional Bag in my hbm.xml file?

How do I make the Bag optional for class Test in the following pseudo hbm.xml?
<class name="Test" table="test">
<bag name="bag" table="example" cascade="all" fetch="join">
<key property-ref="key">
<column name="a_id" />
<column name="b_id" />
</key>
<element column="example_id"
type="my.myclass"/>
</bag></class>
my.mclass is a custom type (my.myclass implements org.hibernate.usertype.UserType)
In the moment if there is no fitting "test example" row in the example table I get an exception?
(I was hoping to find a kind of not-found attribute? But there is no)
What's the relationship between Test and myclass? 1 to many or many to many?
If it's 1 to many in your case, I will suggest you create separate mapping for myclass and use following mapping for Test class
<bag name="bag" table="example" inverse="true" cascade="all" fetch="join">
<key property-ref="key">
<column name="a_id" />
<column name="b_id" />
</key>
<one-to-many class="my.myclass"/>
</bag>

How to validate against schema for namespace, not complete document?

I have a document like this:
<d:block xmlns:d="D" xmlns:b="B" xmlns="default" name="popover">
<d:description>...</d:description>
<d:sample>
<b:popover>
...some b:stuff...
</b:popover>
</d:sample>
</d:block>
Schema for this document looks like:
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="block" ns="D">
<attribute name="name"/>
<element name="description">
<text/>
</element>
<element name="sample">
<ref name="anything"/>
</element>
</element>
</start>
<define name="anything">
<element>
<anyName>
<except>
<nsName ns="D"/>
</except>
</anyName>
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<text/>
<ref name="anything"/>
</choice>
</zeroOrMore>
</element>
</define>
</grammar>
"Anything" literally means anything but D-namespaced.
And I want to create another schema for B namespace to use it against any arbitrary XML containing B:namespace.
How to create Schema for the namespace, not for the complete document?
Can't get this.
A kind of schema like that should work. You just have to define the elements for B namespace in the define element named BElements.
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<ref name="anythingOrB"/>
</start>
<define name="anythingOrB">
<choice>
<ref name="BElements"/>
<ref name="anythingExceptB"/>
</choice>
</define>
<define name="anythingExceptB">
<element>
<anyName>
<except>
<nsName ns="B"/>
</except>
</anyName>
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<text/>
<ref name="anythingOrB"/>
</choice>
</zeroOrMore>
</element>
</define>
<define name="BElements">
<choice>
<element name="elt1" ns="B">
<empty/>
</element>
<element name="elt2" ns="B">
<empty/>
</element>
</choice>
</define>
</grammar>

How to assign array in a BPEL process

I have a simple string as input and after calling a web service which adds the string to an array.Now i have to assign the array to the output(which i have set as a string array in the schema).The enterprise manager gives a fault and says the result contains multiple nodes for the XPath expression given.The Assign activity is shown as pending.So basically how do i assign an array or a list to the output variable which is also set as an array.The wsdl file used is:
<?xml version = '1.0' encoding = 'UTF-8'?>
<definitions
name="ReturnTypeService"
targetNamespace="http://examples2/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://examples2/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
>
<types>
<xsd:schema>
<xsd:import namespace="http://examples2/" schemaLocation="http://localhost:7101/Examples2-Examples2-context-root/ReturnTypePort?xsd=1"/>
</xsd:schema>
</types>
<message name="display">
<part name="parameters" element="tns:display"/>
</message>
<message name="displayResponse">
<part name="parameters" element="tns:displayResponse"/>
</message>
<portType name="ReturnType">
<operation name="display">
<input message="tns:display"/>
<output name="displayResponse"
message="tns:displayResponse"/>
</operation>
</portType>
<binding name="ReturnTypePortBinding" type="tns:ReturnType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="display">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="ReturnTypeService">
<port name="ReturnTypePort" binding="tns:ReturnTypePortBinding">
<soap:address location="http://localhost:7101/Examples2-Examples2-context-root/ReturnTypePort"/>
</port>
</service>
</definitions>
#vanto Is there a way to assign an array from input variable to invoke_input variable?The problem is there are multiple inputs in my web service so i am not able to copy the wrapping element in input variable to wrapping variable in invoke variable.Will copy the snippet of the code here :
<assign name="Assign1">
<copy>
<from variable="inputVariable" part="payload"
query="/ns2:process/ns2:dsaName"/>
<to variable="Invoke1_processList_InputVariable"
part="parameters" query="/ns1:processList/dsaName"/>
</copy>
<copy>
<from variable="inputVariable" part="payload"
query="/ns2:process/ns2:linesOfData"/>
<to variable="Invoke1_processList_InputVariable"
part="parameters" query="/ns1:processList/linesOfData"/>
</copy>
<copy>
<from variable="inputVariable" part="payload"
query="/ns2:process/ns2:description"/>
<to variable="Invoke1_processList_InputVariable"
part="parameters" query="/ns1:processList/description"/>
</copy>
<copy>
<from variable="inputVariable" part="payload"
query="/ns2:process/ns2:application"/>
<to variable="Invoke1_processList_InputVariable"
part="parameters" query="/ns1:processList/application"/>
</copy>
</assign>
The problem is only one is of list type all others are of string type.The XML for this is:
<element name="process">
<complexType>
<sequence>
<element name="dsaName" type="string" minOccurs="0"/>
<element name="linesOfData" type="string" minOccurs="0" maxOccurs="unbounded"/>
<element name="description" type="string" minOccurs="0"/>
</sequence>
</complexType>
</element>
<element name="processResponse">
<complexType>
<sequence>
<element name="result" type="string" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
</schema>
A from-spec and to-spec must not select more than one element or attribute. In your case it appears to select all <return> elements in your variable's part (i.e. the items of the array). Try to copy the element that wraps the items (i.e. the ns1:displayResponse element) and copy this element to ns2:processResponse (the wrapping element in the to-variable).
Since both source and target elements seem to be in different namespaces and are of different types, you probably need to run it through an XSLT script (using doXSLTransform) to translate it from the source schema to the target schema.

XDT Config Transforms - ReplaceAll?

I've got a custom section in my web.config file similar to this structure:
<Messages>
<Message id="1'>
<Property Name="foo" value="bar" />
</Message>
<Message id="2'>
<Property Name="foo" value="bar2" />
</Message>
</Messages>
I want to apply a custom transformation on this such that I can change the value of ALL instances of the Property element with Name="foo" - but I cant seem to get it to work.
I've tried:
<Messages>
<Message>
<Property Name="foo" value="updated" xdt:Locator=Match(Name) xdt:Transform="Replace" />
</Message>
</Mesasges>
I can remove all the elements by replacing the Transform=Replace with a Transform=RemoveAll - any ideas how I can achieve something similar to replace all the values?
It seems like Transform:Replace only replaces the first matched element from the documentation on msdn: ...If more than one element is selected, only the first selected element is replaced. I solved this issue by using a combination of Match-Conditions and SetAttributes, something like:
<Messages>
<Message>
<Property value="updated" xdt:Locator=Condition(#Name='foo') xdt:Transform="SetAttributes(value)" />
</Message>
</Messages>

Resources