Appending multiple strings in Oracle SOA Suit in a BPEL process - oracle

I'm new to the Oracle SOA Suite and I have created a basic BPEL process that allows you to create a "User" with some basic values.
XSD:
//INPUT
<element name="User">
<complexType>
<sequence>
<element name="First_Name" type="string"/>
<element name="Last_Name" type="string"/>
<element name="Age" type="string"/>
<element name="DOB" type="string"/>
</sequence>
</complexType>
</element>
// String to output
<element name="processResponse">
<complexType>
<sequence>
<element name="Output" type="string"/>
</sequence>
</complexType>
</element>
So using this XSD I want to be able to create a user, and append all the values together and create a response/reply with my synchronous BPEL process.
I've tried simply adding all the values together using the '+' operation but doesn't work as it tries to cast it it a integer, so it seems and the value comes out as "Jon NaN".
<copy>
<from>concat("Hello! ", $inputVariable.payload/ns1:Last_Namel)</from>
<to>$outputVariable.payload</to>
</copy>
I've also tried to use multiple concat's but it get's real ugly real quick, and something i would like to avoid is messy code.
So as a summary i want to be able to take all the input values (First Name, Last Name, Age, DOB) and convert them into a nice string with some padding and extra hard coded strings to show a nice message at the end.

Give all the values which you require to be concatenated comma separated in the concat() function:
<from>concat('Hello! ', $inputVariable.payload/ns1:Last_Name,' ',$inputVariable.payload/ns1:First_Name,' ',$inputVariable.payload/ns1:Age,' ',$inputVariable.payload/ns1:DOB)</from>
<to>$outputVariable.payload/Output</to>

Related

Failure of conditional combination index in eXist-db range index

I encountered the following problems in eXist-db configuring range indexes to specify attributes that are worth indexing.
<collection xmlns="http://exist-db.org/collection-config/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<index>
<range>
<create qname="tei:term">
<condition attribute="type" value="main"/>
<field name="mainTerm" type="xs:string"/>
</create>
</range>
</index></collection>
Error occurred:"/db/system/config/db/range/collection.xconf cvc-complex-type.2.4.a: Invalid content was found starting with element 'condition'. One of '{"http://exist-db.org/collection-config/1.0":field}' is expected."
Please help me.
The error you are getting is a schema validation error, triggered by the presence of the <condition> element used by the recently introduced conditional combined index feature.
I've submitted a fix to the error, and for now, you can ignore the error. The schema validation error will not have any effect on the functionality.
General Configuration Structure and Syntax
Index configuration collection.xconf files are standard XML documents that have their elements and attributes defined by the eXist-db namespace http://exist-db.org/collection-config/1.0. The following example shows a configuration example:
<collection xmlns="http://exist-db.org/collection-config/1.0">
<index>
<!-- Full text index based on Lucene -->
<lucene>
<text qname="SPEECH">
<ignore qname="SPEAKER"/>
</text>
<text qname="TITLE"/>
</lucene>
<!-- Range indexes -->
<range>
<create qname="title" type="xs:string"/>
<create qname="author" type="xs:string"/>
<create qname="year" type="xs:integer"/>
</range>
<!-- N-gram indexes -->
<ngram qname="author"/>
<ngram qname="title"/>
</index>
</collection>
To use the new range index, wrap the range index definitions into a range element:
<collection xmlns="http://exist-db.org/collection-config/1.0">
<!--from Tamboti-->
<index xmlns:mods="http://www.loc.gov/mods/v3">
<lucene>
<text qname="mods:title"/>
</lucene>
<!-- Range indexes -->
<range>
<create qname="mods:namePart" type="xs:string" case="no"/>
<create qname="mods:dateIssued" type="xs:string"/>
<create qname="#ID" type="xs:string"/>
</range>
</index>
</collection>
Conditional combined indexes
For combined indexes, you can specify conditions to restrict the values being indexed to those contained in elements that have an attribute meeting certain criteria:
<range>
<create qname="tei:term">
<condition attribute="type" value="main"/>
<field name="mainTerm" type="xs:string"/>
</create>
</range>
This will only index the value of the tei:term element if it has an attribute named type with the value main. Multiple conditions can be specified in an index definition, in which case all conditions need to match in order for the value to be indexed.
Make sure you have a valid xml. For further details, you can read the documentation here: https://exist-db.org/exist/apps/doc/newrangeindex.xml

XPath remove single node (via Saxon CLI)

I want to remove a node from an XML file (using SaxonHE9-8-0-11J):
<project name="Build">
<property name="src" value="src/main/resources" />
<property name="target" value="target/classes" />
<condition property="target.exists">
<available file="target" />
</condition>
</project>
Apparently there are 2 ways I can do this.
XPath1: using a not function
XPath2: using an except clause. But both simply return the entire node-set.
With a not function:
saxonb-xquery -s:test.xml -qs:'*[not(local-name()="condition")]'
With an except clause:
saxonb-xquery -s:test.xml -qs:'* except condition'
With -explain switch the queries are:
<query>
<body>
<filterExpression>
<axis name="child" nodeTest="element()"/>
<operator op="ne (on empty return true())">
<functionCall name="local-name">
<dot/>
</functionCall>
<literal value="condition" type="xs:string"/>
</operator>
</filterExpression>
</body>
</query>
and
<query>
<body>
<operator op="except">
<axis name="child" nodeTest="element()"/>
<path>
<root/>
<axis name="descendant" nodeTest="element(condition, xs:anyType)"/>
</path>
</operator>
</body>
</query>
In general, XPath select nodes from one or more input documents, it doesn't allow you to construct new ones, for that you need XSLT or XQuery. And removing the condition child of the project root, if that is what you want to achieve, is something you need XSLT or XQuery for, with XPath, even if you use /*/(* except condition), you then get all children except the condition element, but as a sequence, not wrapped into a a root.
So with XQuery you could use
/*/element {node-name()} { * except condition }
as a compact but generic way to reconstruct any root with all child elements except the condition: https://xqueryfiddle.liberty-development.net/948Fn5b
Whether you get such an expression through a command line shell is a different problem, on Windows with a Powershell window and the cmd shell it works for me to use
-qs:"/*/element {node-name()} { * except condition }"

XPath Select all elements name of which NOT starts with Capital letter

I Have Schema Name.xsd, it's part of it,need help in framing the query in XPath that
<xsd:complexType name="GetWalletItemBO">
<xsd:sequence>
<xsd:element minOccurs="1" name="paymentOptionId">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
my basic query is like //*[starts-with(name(),'**here I need to put my condition**')]
I have to check that xsd:complexType name starts with Capital letter GetWalletItemBO and not like getWalletItemBO , and on the same way to check that <xsd:element name= starts with small letter paymentOptionId not like PaymentOptionId . *So I try find all elements that HAVE BAD input, don't appropriate to my conditions , that's starts with small letter in xsd:complexType name= ,and with Capital letter in xsd:element name= *.
I think you want:
//xs:complexType[matches(#name, '$\P{Lu}')]
Do not use name() but local-name() to get the name without namespace identifier. Then, split off the first letter and see if it is not contained in the capital letters:
//*[not(contains('ABCDEFGHIJKLMNOPQRSTUVWXYZ', substring(local-name(.), 1, 1)))]

Validate that URI is not empty in RelaxNG

I'm trying to validate that an element always has an href attribute in RelaxNG, and assumed you could do it with this:
<attribute name="href">
<data type="anyURI"/>
</attribute>
Only catch is, apparently anyURI considers empty strings to be valid, so href="" passes with flying colors. Is there any easy way to fix this?
You can use the minLength facet. For example:
<attribute name="href">
<data type="anyURI">
<param name="minLength">5</param>
</data>
</attribute>
See also http://www.w3.org/TR/xmlschema-2/#anyURI

How to escape double quote for Ruby inside of XML

Although I know that I can use &quote, I was wondering if there was a less blunt and long way, such as \", or the like.
Here is an example of the XML:
<root name="test" type="Node" action="{puts :ROOT.to_s}">
<leaf type="Node" decider="{print :VAL1.to_s; gets.chomp.to_i}" action="{puts :ONE.to_s}" />
<leaf type="Node" decider="{print :VAL2.to_s; gets.chomp.to_i}" action="{puts :TWO.to_s}" />
<branch type="Node" decider="{100}" action="{}">
<leaf type="LikelihoodNode" decider="{100}" action="{puts :HI.to_s}" arg="0"/>
</branch>
</root>
The attributes that need this are decider and action. Right now the embedded code is using a little :sym.to_s hack, but that is not a solution.
NOTE: Although the action attribute is only a block in brackets, the processing code pre-pends the lambda.
A double quote inside an XML attribute is written as &quote; (or " or "). You'll have similar issues with single quotes too so you can't use those. However, you can use % as-is in an XML attribute so %|...|, %Q|...|, and %q|...| are available and they're as easy to read and type as quotes:
<root name="test" type="Node" action="{puts %|ROOT|}">
<leaf type="Node" decider="{print %|VAL1|; gets.chomp.to_i}" action="{puts %|ONE|}" />
<!-- ... -->
</root>
Choose whichever delimiters you find the easiest to type and read.
You can also use single quotes for your attributes in XML so you can have:
<leaf type='Node' decider='{print "VAL1"; gets.chomp.to_i}' ...
But then you'd have to use &apos; inside the attribute if you needed to include a single quote.
Alternatively, you could switch to elements instead of attributes:
<leaf type="Node">
<decider><![CDATA[
print "VAL1"
gets.chomp.to_i
]]></decider>
<action><![CDATA[
puts "ONE"
]]></decider>
</leaf>
but that's a bit verbose, ugly, and not as easy to work with as attributes (IMHO).

Resources