p:split-sequence (3.1) 

Splits a sequence of documents.

Summary

<p:declare-step type="p:split-sequence">
  <input port="source" primary="true" content-types="any" sequence="true"/>
  <output port="matched" primary="true" content-types="any" sequence="true"/>
  <output port="not-matched" primary="false" content-types="any" sequence="true"/>
  <option name="test" as="xs:string" required="true"/>
  <option name="initial-only" as="xs:boolean" required="false" select="false()"/>
</p:declare-step>

The p:split-sequence step takes a sequence of documents on its source port and divides this into two sequences, based on the evaluation expression in the test option and the value of the initial-only option.

Ports:

Port

Type

Primary?

Content types

Seq?

Description

source

input

true

any

true

The incoming sequence of documents to split.

matched

output

true

any

true

The documents from the source port for which the test option evaluates to true.

If the initial-only option is true, special processing applies. See the description below.

not-matched

output

false

any

true

The documents from the source port for which the test option evaluates to false.

If the initial-only option is true, special processing applies. See the description below.

Options:

Name

Type

Req?

Default

Description

test

xs:string (XPath expression)

true

 

The XPath boolean expression, as a string, that defines matching. It is evaluated with the document to test as context item (accessible with the dot operator .).

During this evaluation, the position() and last() functions are available to get the position of the document in the sequence and the size of the sequence. See also the Using the position() and last() function example.

initial-only

xs:boolean

false

false

If false (default), all documents for which the expression in the test option is true are considered matched and appear on the matches port. All documents for which this is false are considered not matched and appear on the not-matched port.

If true, special processing applies. See the description below.

Description

The p:split-sequence step works like a switch in a train marshalling yard. A train with document wagons approaches the switch. The switchman has instructions to send a wagon in one direction or the other, depending on the contents of the document. In more technical terms:

  • The p:split-sequence step takes a sequence of documents on its source port.

  • For every document, the XPath boolean expression in the test option is evaluated. During this evaluation, the document is the context item (accessible with the dot operator .).

    The position() and last() functions are available to get the position of the document in the sequence and the size of the sequence (see also the Using the position() and last() function example).

  • If the initial-only option is false:

    • If the result of the test option evaluation is true, the document appears on the matched port.

    • If the result of the test option evaluation is false, the document appears on the not-matched port.

  • If the initial-only option is true:

    • If the result of the test option evaluation is true, the document appears on the matched port, until a document appears for which this expression evaluates to false.

    • The first document for which the test option evaluation is false and all subsequent documents are sent to the not-matched port.

    In other words: it only writes the initial series of matched documents (which may be empty) to the matched port. All other documents are written to the not-matched port, irrespective of the outcome of the test option evaluation.

Examples

Basic usage

This example defines a sequence of <fruit> documents for the source port and splits them based on their color attribute. The final p:wrap-sequence step is only there to be able to show the result as a single document.

Pipeline document:

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0">

  <p:input port="source" sequence="true">
    <fruit name="banana" color="yellow"/>
    <fruit name="orange" color="orange"/>
    <fruit name="lemon" color="yellow"/>
    <fruit name="cauliflower" color="white"/>
  </p:input>
  <p:output port="result"/>

  <p:split-sequence test="/*/@color eq 'yellow'"/>

  <p:wrap-sequence wrapper="matched-documents"/>

</p:declare-step>

Result document:

<matched-documents>
   <fruit color="yellow" name="banana"/>
   <fruit color="yellow" name="lemon"/>
</matched-documents>

All the other source documents appear on the not-matched port, as the following example proofs:

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0">

  <p:input port="source" sequence="true">
    <fruit name="banana" color="yellow"/>
    <fruit name="orange" color="orange"/>
    <fruit name="lemon" color="yellow"/>
    <fruit name="cauliflower" color="white"/>
  </p:input>
  <p:output port="result"/>

  <p:split-sequence test="/*/@color eq 'yellow'"/>

  <p:wrap-sequence wrapper="not-matched-documents">
    <p:with-input pipe="not-matched"/>
  </p:wrap-sequence>

</p:declare-step>

Result document:

<not-matched-documents>
   <fruit color="orange" name="orange"/>
   <fruit color="white" name="cauliflower"/>
</not-matched-documents>

Using the initial-only option

This example shows what happens to the Basic usage example when we set the initial-only option to true. The second source document (about oranges) does not match, so this and all subsequent documents are considered not-matched and sent to the not-matched port. Only the first source document (about bananas) appears on the matched port.

Pipeline document:

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0">

  <p:input port="source" sequence="true">
    <fruit name="banana" color="yellow"/>
    <fruit name="orange" color="orange"/>
    <fruit name="lemon" color="yellow"/>
    <fruit name="cauliflower" color="white"/>
  </p:input>
  <p:output port="result"/>

  <p:split-sequence test="/*/@color eq 'yellow'" initial-only="true"/>

  <p:wrap-sequence wrapper="matched-documents"/>

</p:declare-step>

Result document:

<matched-documents>
   <fruit color="yellow" name="banana"/>
</matched-documents>

Using the position() and last() function

The following example shows that, during evaluation of the test option, the position() and last() functions are available to get the position of the document in the sequence and the size of the sequence. It uses this to match the last document only.

Pipeline document:

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0">

  <p:input port="source" sequence="true">
    <fruit name="banana" color="yellow"/>
    <fruit name="orange" color="orange"/>
    <fruit name="lemon" color="yellow"/>
    <fruit name="cauliflower" color="white"/>
  </p:input>
  <p:output port="result"/>

  <p:split-sequence test="position() eq last()"/>

  <p:wrap-sequence wrapper="matched-documents"/>

</p:declare-step>

Result document:

<matched-documents>
   <fruit color="white" name="cauliflower"/>
</matched-documents>

Additional details

  • p:split-sequence preserves all document-properties of the document(s) appearing on its source port.

Errors raised

Error code

Description

XC0150

It is a dynamic error if evaluating the XPath expression in option test on a context document results in an error.

Reference information

This description of the p:split-sequence step is for XProc version: 3.1. This is a required step (an XProc 3.1 processor must support this).

The formal specification for the p:split-sequence step can be found here.

The p:split-sequence step is part of categories:

The p:split-sequence step is also present in version: 3.0.