|
39 | 39 | import java.io.IOException;
|
40 | 40 | import java.io.InputStream;
|
41 | 41 |
|
| 42 | +import static org.exist.xquery.FunctionDSL.*; |
| 43 | +import static org.exist.xquery.functions.fn.FnModule.functionSignatures; |
| 44 | + |
42 | 45 | /**
|
43 | 46 | * Functions related to JSON parsing.
|
44 | 47 | *
|
45 | 48 | * @author Wolf
|
46 | 49 | */
|
47 | 50 | public class JSON extends BasicFunction {
|
48 | 51 |
|
49 |
| - public static final FunctionSignature[] signatures = { |
50 |
| - new FunctionSignature( |
51 |
| - new QName("parse-json", Function.BUILTIN_FUNCTION_NS), |
52 |
| - "Parses a string supplied in the form of a JSON text, returning the results typically in the form of a map or array.", |
53 |
| - new SequenceType[]{ |
54 |
| - new FunctionParameterSequenceType("json-text", Type.STRING, Cardinality.ZERO_OR_ONE, "JSON string") |
55 |
| - }, |
56 |
| - new FunctionReturnSequenceType(Type.ITEM, Cardinality.ZERO_OR_ONE, "The parsed data, typically a map, array or atomic value") |
57 |
| - ), |
58 |
| - new FunctionSignature( |
59 |
| - new QName("parse-json", Function.BUILTIN_FUNCTION_NS), |
60 |
| - "Parses a string supplied in the form of a JSON text, returning the results typically in the form of a map or array.", |
61 |
| - new SequenceType[]{ |
62 |
| - new FunctionParameterSequenceType("json-text", Type.STRING, Cardinality.ZERO_OR_ONE, "JSON string"), |
63 |
| - new FunctionParameterSequenceType("options", Type.MAP, Cardinality.EXACTLY_ONE, "Parsing options") |
64 |
| - }, |
65 |
| - new FunctionReturnSequenceType(Type.ITEM, Cardinality.ZERO_OR_ONE, "The parsed data, typically a map, array or atomic value") |
66 |
| - ), |
67 |
| - new FunctionSignature( |
68 |
| - new QName("json-doc", Function.BUILTIN_FUNCTION_NS), |
69 |
| - "Reads an external (or database) resource containing JSON, and returns the results of parsing the resource as JSON. An URL parameter " + |
70 |
| - "without scheme or scheme 'xmldb:' is considered to point to a database resource.", |
71 |
| - new SequenceType[]{ |
72 |
| - new FunctionParameterSequenceType("href", Type.STRING, Cardinality.ZERO_OR_ONE, "URL pointing to a JSON resource") |
73 |
| - }, |
74 |
| - new FunctionReturnSequenceType(Type.ITEM, Cardinality.ZERO_OR_ONE, "The parsed data, typically a map, array or atomic value") |
75 |
| - ), |
76 |
| - new FunctionSignature( |
77 |
| - new QName("json-doc", Function.BUILTIN_FUNCTION_NS), |
78 |
| - "Reads an external (or database) resource containing JSON, and returns the results of parsing the resource as JSON. An URL parameter " + |
79 |
| - "without scheme or scheme 'xmldb:' is considered to point to a database resource.", |
80 |
| - new SequenceType[]{ |
81 |
| - new FunctionParameterSequenceType("href", Type.STRING, Cardinality.ZERO_OR_ONE, "URL pointing to a JSON resource"), |
82 |
| - new FunctionParameterSequenceType("options", Type.MAP, Cardinality.EXACTLY_ONE, "Parsing options") |
83 |
| - }, |
84 |
| - new FunctionReturnSequenceType(Type.ITEM, Cardinality.ZERO_OR_ONE, "The parsed data, typically a map, array or atomic value") |
85 |
| - ), |
86 |
| - new FunctionSignature( |
87 |
| - new QName("json-to-xml", Function.BUILTIN_FUNCTION_NS), |
88 |
| - "Parses a string supplied in the form of a JSON text, returning the results in the form of an XML document node.", |
89 |
| - new SequenceType[]{ |
90 |
| - new FunctionParameterSequenceType("json-text", Type.STRING, Cardinality.ZERO_OR_ONE, "JSON text as defined in [RFC 7159]. The function parses this string to return an XDM value"), |
91 |
| - }, |
92 |
| - new FunctionReturnSequenceType(Type.ITEM, Cardinality.ZERO_OR_ONE, "The parsed data as XML") |
93 |
| - ), |
| 52 | + private static final FunctionParameterSequenceType FS_PARAM_JSON_TEXT = optParam("json-text", Type.STRING, "JSON text as defined in [RFC 7159]. The function parses this string to return an XDM value"); |
| 53 | + private static final FunctionParameterSequenceType FS_PARAM_HREF = optParam("href", Type.STRING,"URL pointing to a JSON resource"); |
| 54 | + private static final FunctionParameterSequenceType FS_PARAM_OPTIONS = param("options", Type.MAP, "Parsing options"); |
| 55 | + |
| 56 | + private static final String FS_PARSE_JSON_NAME = "parse-json"; |
| 57 | + static final FunctionSignature[] FS_PARSE_JSON = functionSignatures( |
| 58 | + FS_PARSE_JSON_NAME, |
| 59 | + "Parses a string supplied in the form of a JSON text, returning the results typically in the form of a map or array.", |
| 60 | + returnsOpt(Type.ITEM, "The parsed data, typically a map, array or atomic value"), |
| 61 | + arities( |
| 62 | + arity( |
| 63 | + FS_PARAM_JSON_TEXT |
| 64 | + ), |
| 65 | + arity( |
| 66 | + FS_PARAM_JSON_TEXT, |
| 67 | + param("options", Type.MAP, "Parsing options") |
| 68 | + ) |
| 69 | + ) |
| 70 | + ); |
94 | 71 |
|
95 |
| - new FunctionSignature( |
96 |
| - new QName("json-to-xml", Function.BUILTIN_FUNCTION_NS), |
97 |
| - "Parses a string supplied in the form of a JSON text, returning the results in the form of an XML document node.", |
98 |
| - new SequenceType[]{ |
99 |
| - new FunctionParameterSequenceType("json-text", Type.STRING, Cardinality.ZERO_OR_ONE, "JSON text as defined in [RFC 7159]. The function parses this string to return an XDM value"), |
100 |
| - new FunctionParameterSequenceType("options", Type.MAP, Cardinality.EXACTLY_ONE, "Parsing options") |
101 |
| - }, |
102 |
| - new FunctionReturnSequenceType(Type.ITEM, Cardinality.ZERO_OR_ONE, "The parsed data as XML") |
103 |
| - ) |
104 |
| - }; |
| 72 | + private static final String FS_JSON_DOC_NAME = "json-doc"; |
| 73 | + static final FunctionSignature[] FS_JSON_DOC = functionSignatures( |
| 74 | + FS_JSON_DOC_NAME, |
| 75 | + "Reads an external (or database) resource containing JSON, and returns the results of parsing the resource as JSON. An URL parameter " + |
| 76 | + "without scheme or scheme 'xmldb:' is considered to point to a database resource.", |
| 77 | + returnsOpt(Type.ITEM, "The parsed data, typically a map, array or atomic value"), |
| 78 | + arities( |
| 79 | + arity( |
| 80 | + FS_PARAM_HREF |
| 81 | + ), |
| 82 | + arity( |
| 83 | + FS_PARAM_HREF, |
| 84 | + FS_PARAM_OPTIONS |
| 85 | + ) |
| 86 | + ) |
| 87 | + ); |
| 88 | + |
| 89 | + private static final String FS_JSON_TO_XML_NAME = "json-to-xml"; |
| 90 | + static final FunctionSignature[] FS_JSON_TO_XML = functionSignatures( |
| 91 | + FS_JSON_TO_XML_NAME, |
| 92 | + "Parses a string supplied in the form of a JSON text, returning the results in the form of an XML document node.", |
| 93 | + returnsOpt(Type.ITEM, "The parsed data as XML"), |
| 94 | + arities( |
| 95 | + arity( |
| 96 | + FS_PARAM_JSON_TEXT |
| 97 | + ), |
| 98 | + arity( |
| 99 | + FS_PARAM_JSON_TEXT, |
| 100 | + FS_PARAM_OPTIONS |
| 101 | + ) |
| 102 | + ) |
| 103 | + ); |
105 | 104 |
|
106 | 105 | public static final String OPTION_DUPLICATES = "duplicates";
|
107 | 106 | public static final String OPTION_DUPLICATES_REJECT = "reject";
|
@@ -139,9 +138,9 @@ public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathExce
|
139 | 138 |
|
140 | 139 | JsonFactory factory = createJsonFactory(liberal);
|
141 | 140 |
|
142 |
| - if (isCalledAs("parse-json")) { |
| 141 | + if (isCalledAs(FS_PARSE_JSON_NAME)) { |
143 | 142 | return parse(args[0], handleDuplicates, factory);
|
144 |
| - } else if (isCalledAs("json-to-xml")) { |
| 143 | + } else if (isCalledAs(FS_JSON_TO_XML_NAME)) { |
145 | 144 | return toxml(args[0], handleDuplicates, factory);
|
146 | 145 | } else {
|
147 | 146 | return parseResource(args[0], handleDuplicates, factory);
|
@@ -359,7 +358,6 @@ public static void jsonToXml(MemTreeBuilder builder, JsonParser parser) throws I
|
359 | 358 | if(parser.getCurrentName() != null){
|
360 | 359 | builder.addAttribute(KEY, parser.getCurrentName());
|
361 | 360 | }
|
362 |
| - // according to spec, all numbers are converted to double |
363 | 361 | builder.characters(parser.getText());
|
364 | 362 | builder.endElement();
|
365 | 363 |
|
|
0 commit comments