How hard can it be?

Henry S. Thompson
26 Feb 2016

1. Made up requirement for an example pipeline: Lighten-up

1.1. Version 1

Input document has product elements with colour attributes, whose value is a word.

Command line provides a value for 'language', 'match' and 'attr' options

Pipeline should change all dark colours to light ones, e.g. 'red' to 'pink' and 'rouge' to 'rose', for English and French respectively

Suppose we already have a step called 'my:dyer', which takes a single input document, a match pattern, a map and an attribute name as options, and whenever the value of the match pattern is satisfied and its value is a key in the map, it the relevant attribute is replaced by map(key).

Suppose further we have json files locally available named english.json, french.json containing the necessary maps.

What does the pipeline to do the job look like?

As of today, you can find an XProc v.1 approximation to this (dyer.xpl), which given the other files here (e.g. english.xml and catalogue_e.xml) will actually work, using Calabash as follows:

xproc -i source=catalogue_e.xml dyer.xpl language=english
match="//product[@colour]"

So will the French version.

There is also a (simpler, but not very much simpler :-( XProcXML v.2 version in dyer_2.xpl.

1.2. Version 2

As above, but instead of the command line, the input document has an xml:lang attribute on the document element, with values 'en', 'fr', etc.

2. Assertion/API semantics

2.1. Version 1

Here's my first cut at an abstract API representation of the XProc2[XML] pipeline for version 1 of this example.

G = TopLevelContext() # has bindings from command-line
v1 == XPathEval($i_source,G)
v2 == XPathEval("{$op_language}.json",G)
v3 == XPathEval($op_match,G)
v4 == XPathEval($op_attr,G)
v5 == XPathEval($o_result,G)
s1 == StepImpl(p:load,uri=v1)
Pipe(s1.result,s4.source,xml)
s2 == StepImpl(p:load,uri=v2,override-content-type="application/json")
Pipe(s2.result,s3.source,json)
s3 == StepImpl(p:json-to-xdm)
Pipe(s3.result,v6,xdm)
C1 == PushContext(G,.=v6)
v7 == XPathEval(?colourMap,C1)
C2 == PushContext(C1,lexmap=v7)
v8 == XPathEval($lexmap,C2)
s4 == StepImpl(my:dyer,match=v3,lex=v8,attr=v4)
Pipe(s4.result,s5.source,xml)
s5 == StepImpl(p:serialize)
Pipe(s5.result,v5,text/plain)

That's the top-level pipeline. The definition of the my:dyer step looks like this:

S = StepContext() # has bindings from step invocation

[under construction]