p:string-replace (3.0) 
Replaces nodes with strings.
<p:declare-step type="p:string-replace"> <input port="source" primary="true" content-types="xml html" sequence="false"/> <output port="result" primary="true" content-types="text xml html" sequence="false"/> <option name="match" as="xs:string" required="true"/> <option name="replace" as="xs:string" required="true"/> </p:declare-step>
The p:string-replace step takes the document appearing on its source port and replaces nodes matching the match option
with a string that is computed using the XPath expression in the replace option.
Ports:
Port | Type | Primary? | Content types | Seq? | Description |
|---|---|---|---|---|---|
|
|
|
|
| The document to replace the nodes in. |
|
|
|
|
| The resulting document. |
Options:
The p:string-replace step does the following:
It takes the document appearing on its source port and holds the XSLT selection pattern in the match
option against this.
For each node matched:
The matched node becomes the context item (accessible with the dot operator .).
The XPath expression in the replace option is evaluated and the result is turned into a string.
If the matched node is an attribute, the value of the attribute is replaced with this string.
If the document-node is matched, the full document will be replaced by the string (and the result will therefore be a text document).
In all other cases, the full node is replaced by the string.
So this step replaces the matched node(s) with the result of a dynamically evaluated expression. This doesn’t mean this expression can’t be a constant: see the Basic usage example). However, it allows you to do all kinds of nifty calculations, based on where the match is: see the Advanced usage example.
This step replaces matched nodes with strings. If you need to replace matched nodes with full documents, have a look at the p:replace step.
The following example simply replaces the thing’s <contents> element with a (constant) description:
Source document:
<thing> <contents/> </thing>
Pipeline document:
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0"> <p:input port="source"/> <p:output port="result"/> <p:string-replace match="thing/contents" replace="'This is a thing of beauty!'"/> </p:declare-step>
Result document:
<thing>
This is a thing of beauty!
</thing>Please notice the single quotes around the value in the replace option. This option must not hold just some value but an
XPath expression. This means that if you need a constant string, you need to write it as an XPath string, therefore the
single quotes.
If the match option matches an attribute, the value of the attribute is
replaced:
Source document:
<thing description="notfilledinyet"/>
Pipeline document:
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0"> <p:input port="source"/> <p:output port="result"/> <p:string-replace match="thing/@description" replace="'This is a thing of beauty!'"/> </p:declare-step>
Result document:
<thing description="This is a thing of beauty!"/>
The following example fills empty description attributes with a value based on the index/occurrence of the parent
<thing> element and the value of its name attribute:
Source document:
<things> <thing name="brick" description=""/> <thing name="mortar" description=""/> <thing name="door" description="A door"/> </things>
Pipeline document:
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0"> <p:input port="source"/> <p:output port="result"/> <p:string-replace match="thing/@description[. eq '']" replace="'Thing ' || count(../preceding-sibling::thing) + 1 || ': ' || ../@name"/> </p:declare-step>
Result document:
<things> <thing name="brick" description="Thing 1: brick"/> <thing name="mortar" description="Thing 2: mortar"/> <thing name="door" description="A door"/> </things>
Notice that to be able to perform this trick, the description attribute must already be there! A <thing> element
without such an attribute will not be changed. So if you have content where this is lacking, you’ll need to prepare it. In this case we
use the p:add-attribute step to add a description attribute to any <thing> element that is lacking one
first:
Source document:
<things> <thing name="brick" description=""/> <thing name="screw"/> <thing name="mortar" description=""/> <thing name="door" description="A door"/> </things>
Pipeline document:
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0"> <p:input port="source"/> <p:output port="result"/> <p:add-attribute match="thing[empty(@description)]" attribute-name="description" attribute-value=""/> <p:string-replace match="thing/@description[. eq '']" replace="'Thing ' || count(../preceding-sibling::thing) + 1 || ': ' || ../@name"/> </p:declare-step>
Result document:
<things> <thing name="brick" description="Thing 1: brick"/> <thing description="Thing 2: screw" name="screw"/> <thing name="mortar" description="Thing 3: mortar"/> <thing name="door" description="A door"/> </things>
Options can also be set using the <p:with-option> element. If you use this for the replace option, make sure that
you pass the expression in the replace option as a string. If you don’t, it will get evaluated by
the pipeline, before the invocation of the p:string-replace step, and that is very probably not what you intend. Here is an example of how to do this
right, based on the first example of Advanced usage:
Source document:
<things> <thing name="brick" description=""/> <thing name="mortar" description=""/> </things>
Pipeline document:
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0">
<p:input port="source"/>
<p:output port="result"/>
<p:string-replace match="thing/@description">
<p:with-option name="replace" select="'''Thing '' || count(../preceding-sibling::thing) + 1 || '': '' || ../@name'"/>
</p:string-replace>
</p:declare-step>Result document:
<things> <thing name="brick" description="Thing 1: brick"/> <thing name="mortar" description="Thing 2: mortar"/> </things>
If you accidentally write the p:with-option/@select as the value of the p:string-replace/@replace attribute in
Advanced usage (an easy and probable mistake to make), the XProc processor will raise an error:
The expression in the p:with-option/@select is executed by the pipeline first and results in:
'Thing 1:'
This is not a valid XPath expression…
The p:string-replace step tries to evaluate Thing 1: as an expression and fails miserably (but rightly).
p:string-replace preserves all document-properties of the document(s) appearing on its source port.
There is one exception: if the resulting document contains only text, the content-type document-property is changed to
text/plain and the serialization document-property is removed.
If an attribute called xml:base is added or changed, the base URI of the element is updated accordingly. See also category
Base URI related.
This description of the p:string-replace step is for XProc version: 3.0. This is a required step (an XProc 3.0 processor must support this).
The formal specification for the p:string-replace step can be found here.
The p:string-replace step is part of categories:
The p:string-replace step is also present in version:
3.1.