Hi Ron,
The examples are very useful!
A couple of comments:
-
Considering
that we are using XML info-set terminology, I was wondering if we should say ‘as
the document element property of the source DII’ instead of ‘as
the single child of the root node of the source tree’ when explaining the source node-set?
-
I was
under the impression that XSLT variables and params are identified by a QName, so
shouldn’t we name the BPEL variables as ‘bpws:foo’? Or was the
rationality to keep the names unqualified for simplicity sake? The advantage of
qualifying them using the BPEL URI would be that it avoid name clashes, wouldn’t
it?
-
As doXslTransform
is a xpath function, it can in theory be used in while condition expressions,
join condition expression, until expression, etc. Is this allowed? If it is,
shouldn’t we propagate BPEL links, partnerLinks, and properties, to the
XSLT engine as well?
Also, although this is not relevant to
this proposal in question, I think it is interesting to consider that the
XUpdate committee has re-started its activities recently…
Best regards,
From: Ron Ten-Hove [mailto:Ronald.Ten-Hove@Sun.COM]
Sent: Tuesday, October 11, 2005
2:41 PM
To: wsbpeltc
Subject: [wsbpel] Issue - 11 -
Proposal (after off-line discussions)
Folks,
Last week I sent out a message outlining three related variants to
a solution for issue 11. This message details one of those variants (the XPath
extension function), as further developed by a subgroup of our TC. This serves
as an update to the proposal I made last week, amending Ugo's proposed solution
for issue 11.
This proposal has two parts: proposed changes to the
specification, and a couple of illustrative examples.
My thanks to all those who helped develop this proposal.
(All the good stuff came from them; the typos are all mine. :-)
Best regards,
-Ron
P.S. A warning: this is best viewed using an HTML-enabled mail reader. Plain
text will likely be a bit messy, and harder to read.
Section 9.4: append the following:
The above copy mechanism, when combined with the
default XPath 1.0 expression language, cannot perform complex XML
transformations. To address this restriction in a portable fashion, a WS-BPEL
processor MUST support the bpws:doXslTransform() XPath 1.0
extension function, as described in the following paragraphs.
Function signature: Object bpws:doXslTransform(String, node-set)
where:
- The first parameter (an XPath String) provides a
URI naming the style sheet to be used by the WS-BPEL processor.
- The second parameter (an XPath node set) provides
the source document for the transformation to be performed by the WS-BPEL
processor. This set must contain a single EII (i.e. an element node in
XPath 1.0 data model); if it does not, the WS-BPEL processor MUST throw a bpws:invalidXsltParams
fault. The single EII as specified by this parameter MUST be treated as
the single child of the root node of the source tree for XSLT processing.
- The result of the function MUST provide the
result of the transformation. It will be one of the following infoset
items, depending on the XSLT output method employed by the selected style
sheet:
- A single TII (an
XPath 1.0 text node), created by the "text" or "html"
output methods, or
- A single EII (an
XPath element node that is the single child of the root of the result
tree), which is created by the "xml" output method.
The WS-BPEL processor MUST execute the bpws:doXslTransform
method such that all of the following apply:
- The first parameter, naming the style sheet to be
used, MUST be used to find the style sheet corresponding to the given URI.
This is accomplished in an implementation-dependent fashion. If the style
sheet corresponding to the given URI cannot be found, the WS-BPEL
processor MUST throw a bpws:invalidXsltParams fault.
- The processor MUST perform an XSLT 1.0
transformation, as described in section 5.1 (Processing Model) of the XSLT
1.0 specification, using the named style sheet as primary sheet sheet, the
provided root node as the source document, and the result tree as the
result of the transformation.
- Global parameters (section 11.4 of [XSLT 1.0])
are used to pass BPEL variables to the XSLT processor. XSLT global
parameters are matched to BPEL variables by name.1 The WS-BPEL
processor MUST map BPEL variables that are accessible in the scope of the
activity containing the bpws:doXslTransform function
call to the global parameters declared in the style sheet. A global
parameter that does not have a matching BPEL variable name MUST retain its
default value, as declared in the style sheet. A WS-BPEL processor MAY
warn users of any top-level parameters in the named style sheet not
matched by in-scope WS-BPEL variables.
- Any XSLT processing faults that occur during the
transformation MUST result in a bpws:subLanguageExecutionFault
being thrown.
Note that because XSLT is a side effect-free language,
execution of the transformation cannot (by definition) cause any changes to
BPEL variables referred to in the style sheet.
1 Note that XSLT global parameters must use NCNames to order to
match the NCNames used for BPEL variable names; QNames will not match.
Section A (Standard Faults): add the following faults
to the table:
Fault Name
|
Reason
|
invalidXsltParams
|
An invalid parameter was provided for a bpws:doXslTransform
function call
|
bpws:doXslTransform Example
Complex document transformation. A
common pattern in BPEL processes involves a sequence of receiving an XML
document from one service, converting it to a different schema to form a new
request message, and sending the new request to another service. Such
documentation conversion is easier accomplished using XSLT, using the
doXslTransform function For example:
<variables>
<variable name="A"
type="foo:AType"/>
<variable name="B"
type="bar:BType"/>
</variables>
...
<sequence>
<invoke ...
inputVariable="..." outputVariable="A"/>
<assign>
<from>
<expression>
bpws:doXslTransform("urn:stylesheets:A2B.xsl",
$A)
</expression>
</from>
<to
variable="B"/>
</assign>
<invoke ...
inputVariable="B".../>
</sequence>
In the sequence, a service is invoked, and the result
(of type foo:AType) copied to variable A. The assign activity is used to
transform the contents of variable A to type bar:BType, and copy the result of
that transformation to variable B. Variable B is used to invoke another
service.
The style sheet A2B.xsl would contain the XSL rules for converting documents of
schema foo:AType to schema bar:BType.
Iterative document construction and BPEL
variable access. Suppose that we are constructing a document by
repeatedly calling a service, and accumulating the result in an XML variable.
The loop might look something like this:
<variables>
<variable name="PO"
type="foo:POType"/>
<variable
name="OutVar" type="foo:ItemType"/>
</variables>
<!-- ... PO is
initialized ... -->
<!-- Iteratively add more items to PO until complete -->
<while>
<condition>...not
done...</condition>
<sequence>
<!--
Fetch next chunk into OutVar -->
<invoke ...
inputVariable="..." outputVariable="OutVar"/>
<assign>
<from>
<expression>
bpws:doXslTransform("urn:stylesheets:AddToPO.xsl",
$PO)
</expression>
</from>
<to variable="PO"/>
</assign>
</sequence>
</while>
To allow the XSLT style sheet access to the OutVar
variable from the BPEL process, it must contain a global (top-level) parameter
with the same name:
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- OutVar variable from
BPEL process; defaults to empty
item
-->
<xsl:param name = "OutVar"><item/></xsl:param>
...
</xsl:transform>
The style sheet would contain a template similar to the
following, responsible for appending OutVar
(the new item) to the existing list of items in the PO
variable.
<xsl:template
match="item">
<!-- line 1 -->
<xsl:copy-of
select="."/>
<!-- line 2 -->
<xsl:if
test="position()=last()"> <!-- line 3
-->
<xsl:copy-of select="$OutVar"/>
<!-- line 4 -->
</xsl:if>
<!-- line 5 -->
</xsl:template>
<!-- line 6 -->
This template copies all existing items in the source
document (lines 1 & 2), and appends the contents of the BPEL variable OutVar
to the list of items (line 3 tests to see if the current node is at the end of
the item list; line 4 copies the result-tree fragment from the BPEL variable OutVar
to follow the the last item. Thus, if PO has a
value of:
<po><item>item 1</item></po>
at the beginning of an iteration of the the above
loop, and the <invoke> activity returns a
value of <item>FooBar</item>,
evaluation of the <from> expression will result in a value of:
<po><item>item
1</item><item>FooBar</item></po>
which, when the BPEL copy
activity is complete, will become the new value of the PO
variable.