p:json-merge (3.1) 

Joins documents into a JSON map document.

Summary

<p:declare-step type="p:json-merge">
  <input port="source" primary="true" content-types="any" sequence="true"/>
  <output port="result" primary="true" content-types="application/json" sequence="false"/>
  <option name="duplicates" as="item()*" required="false" select="'use-first'" values="('reject', 'use-first', 'use-last', 'use-any', 'combine')"/>
  <option name="key" as="xs:string" required="false" select="'concat("_",$p:index)'"/>
</p:declare-step>

The p:json-merge step merges the document(s) appearing on the source port into a JSON map. This map is returned as a single JSON document on the result port.

Ports:

Port

Type

Primary?

Content types

Seq?

Description

source

input

true

any

true

The documents to join.

result

output

true

application/json

false

The resulting JSON map document containing the source documents.

Options:

Name

Type

Req?

Default

Description

duplicates

item()*

false

use-first

Specifies what to do with duplicate keys in the resulting map. See Handling duplicates.

key

xs:string (XPath expression)

false

concat("_",$p:index)

An XPath expression that computes the value for the key of an entry in the resulting map.

This expression is evaluated with the document it is applied to as context item. A variable $p:index is available that holds the index (sequence number) of the document on the source port.

See Computing a different key for an example of how to use this option.

Description

The p:json-merge step takes the document(s) appearing on its source port and joins them into a JSON map (also know as JSON object). How the source documents end up in the resulting map depends on their type:

  • For a JSON source document that is a map, all key/value pairs are copied into the result map.

  • For JSON documents that are not a map, XML, HTML and text documents, a new key/value pair is created. The key is computed using the XPath expression in the key option. Regarding their value:

    • A JSON document is used as is.

    • An XML, HTML or text document is first serialized (as if written to disk) and then added as a string to the resulting array.

  • Whether p:json-merge can handle any other media types is implementation-defined and therefore dependent on the XProc processor used.

Handling duplicates

While filling up the result map, it can happen that a key is already present. Duplicate keys are not allowed. What happens in case of a duplicate key depends on the value of the duplicates option:

Value

Description

reject

When a duplicate key is detected, error XC0106 is raised

use-first (default)

When a duplicate key is detected, the already present entry is used and the duplicate one is discarded.

use-last

When a duplicate key is detected, the already present entry is discarded and the duplicate one is used.

use-any

When a duplicate key is detected, it is implementation-defined which one is retained.

combine

When a duplicate key is detected, the values for both keys are turned into a sequence.

Watch out: A sequence of data as value in a map is perfectly fine in the general XPath data model. This means that you can use a result with combined values in your pipeline without problems. However, it is not allowed in JSON, so when you try to serialize such a map as a JSON document, an error will occur.

See Handling duplicates for an example.

Examples

Basic usage

The following pipeline produces a sequence of 3 documents on the source port of p:json-merge: An XML, a JSON map and a text document. This is merrily joined into a single map. Notice that the key/value pairs of the JSON map source document are now part of the resulting map.

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

  <p:input port="source" sequence="true">
    <p:inline><some-xml a="b"/></p:inline>
    <p:inline content-type="application/json" expand-text="false">{"key": 12345, "debug": true}</p:inline>
    <p:inline content-type="text/plain">Hello there!</p:inline>
  </p:input>
  <p:output port="result"/>

  <p:json-merge/>

</p:declare-step>

Result document:

{"_1":"<some-xml a=\"b\"\/>","key":12345,"debug":true,"_3":"Hello there!"}

Computing a different key

The following pipeline produces a sequence of 3 documents on the source port of p:json-merge: An XML document, a JSON map and another XML document. With the key option we set the key for the result map to the local name of the root elements: local-name(/*). Notice that what happens with the keys for the second source document, which is itself a map, is not affected.

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

  <p:input port="source" sequence="true">
    <p:inline><some-xml a="b"/></p:inline>
    <p:inline content-type="application/json" expand-text="false">{"key": 12345, "debug": true}</p:inline>
    <p:inline><some-more-xml c="d"/></p:inline>
  </p:input>
  <p:output port="result"/>

  <p:json-merge key="local-name(/*)"/>

</p:declare-step>

Result document:

{"some-xml":"<some-xml a=\"b\"\/>","key":12345,"debug":true,"some-more-xml":"<some-more-xml c=\"d\"\/>"}

Handling duplicates

The following pipeline produces a sequence of 2 JSON map documents on the source port of p:json-merge. Both maps contain an entry with the key dupkey. With duplicates="use-last" we specify that the last one must be used.

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

  <p:input port="source" sequence="true">
    <p:inline content-type="application/json" expand-text="false">{"dupkey": "a", "debug": true}</p:inline>
    <p:inline content-type="application/json" expand-text="false">{"dupkey": "b"}</p:inline>
  </p:input>
  <p:output port="result"/>

  <p:json-merge duplicates="use-last"/>

</p:declare-step>

Result document:

{"debug":true,"dupkey":"b"}

Additional details

  • No document-properties of the source document(s) survive.

  • The resulting document has no base-uri property.

  • If there are no documents appearing on the source port, the result port returns the empty sequence.

Errors raised

Error code

Description

XC0106

It is a dynamic error if duplicate keys are encountered and option duplicates has value “reject”.

XC0107

It is a dynamic error if a document of a not supported document type appears on port source of p:json-merge.

XC0110

It is a dynamic error if the evaluation of the XPath expression in option key for a given item returns either a sequence, an array, a map, or a function.

Reference information

This description of the p:json-merge 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:json-merge step can be found here.

The p:json-merge step is part of categories:

The p:json-merge step is also present in version: 3.0.