My goal for my Xproc pipeline below is to take in a source XML document, run 2 XSLT transforms with <p:xslt>
steps, then feed the output XML after the 2nd <p:xslt>
to the <c:body>
of the <p:http-request>
step:
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
xmlns:c="http://www.w3.org/ns/xproc-step"
version="1.0">
<p:input port="source" primary="true"/>
<p:output port="result" primary="true"/>
<p:serialization port="result"
indent="false"
method="xml"
encoding="utf-8"
omit-xml-declaration="false"
doctype-system="myDTD.dtd"
doctype-public="-//DOCTYPE-HERE"/>
<p:xslt>
<p:input port="stylesheet">
<p:document href="XSLT-1.xslt"/>
</p:input>
</p:xslt>
<p:xslt>
<p:input port="stylesheet">
<p:document href="XSLT-2.xslt"/>
</p:input>
</p:xslt>
<p:http-request omit-xml-declaration="false"
encoding="UTF-8">
<p:input port="source">
<p:inline>
<c:request href="http://localhost:80/myRESTserver/dburi/myDOC.xml"
auth-method="basic"
username="user"
password="admin"
method="put">
<c:body content-type="text/xml" >
</c:body>
</c:request>
</p:inline>
</p:input>
</p:http-request>
Is there a way to achieve this? When I try executing this code as is, the <p:http-request>
is invoked first (PUTS an empty XML file into the database).
The reason why
p:http-request
runs first is that it does not depend on any other steps in the pipeline. Thesource
input port ofp:http-request
is bound to a static inlinec:request
document and therefore the step does not need to wait for any other steps to finish first. The step can therefore run at any time.To fix that, you need to connect the input port of
p:http-request
to the secondp:xslt
step. This can be done explicitly (usingp:pipe
) or implicitly (relying on the fact that the XProc processor will manufacture impliedp:pipe
connections automatically). Let's demonstrate both while solving your main question (embedding the output ofp:xslt
inc:body
) in the process:For embedding XML content in XML wrappers, the usual go-to XProc steps are
p:wrap
andp:wrap-sequence
. However, they work with simple (one level) XML wrapper elements, so they are not all that helpful if you want to wrap in multiple levels of XML (as in your case:c:request/c:body
). So you have to use something else - for example thep:insert
step:Let's take a look at what this does:
p:xslt
step a name (xslt2
).p:identity
step in between the secondp:xslt
step and thep:http-request
step. Thep:identity
step uses a staticc:request/c:body
document as the insertion target and the output of the step namedxslt2
as the content to be inserted. It inserts the content as the first child ofc:request/c:body
.source
input port of thep:http-request
. This is fine because the output of thep:insert
step will flow into thesource
input port ofp:http-request
automatically.