Skip to content

Commit 77a8330

Browse files
authored
Merge pull request #16 from evolvedbinary/7.x.x/hotfix/xmldb-serialize-array-map
[7.x.x] Allow XDM Array and Map types to be serialized over the XML:DB API
2 parents 29429e7 + 1b6303c commit 77a8330

File tree

5 files changed

+96
-5
lines changed

5 files changed

+96
-5
lines changed

exist-core/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,7 @@
958958
<include>src/main/java/org/exist/xmldb/LocalXMLResource.java</include>
959959
<include>src/main/java/org/exist/xmldb/RemoteRestoreService.java</include>
960960
<include>src/test/java/org/exist/xmldb/ResourceTest.java</include>
961+
<include>src/test/java/org/exist/xmldb/SerializationTest.java</include>
961962
<include>src/test/java/org/exist/xmldb/TestEXistXMLSerialize.java</include>
962963
<include>src/test/java/org/exist/xmldb/TreeLevelOrderTest.java</include>
963964
<include>src/test/java/org/exist/xmldb/concurrent/XMLGenerator.java</include>
@@ -1312,6 +1313,7 @@
13121313
<exclude>src/main/java/org/exist/xmldb/LocalXMLResource.java</exclude>
13131314
<exclude>src/main/java/org/exist/xmldb/RemoteRestoreService.java</exclude>
13141315
<exclude>src/test/java/org/exist/xmldb/ResourceTest.java</exclude>
1316+
<exclude>src/test/java/org/exist/xmldb/SerializationTest.java</exclude>
13151317
<exclude>src/test/java/org/exist/xmldb/TestEXistXMLSerialize.java</exclude>
13161318
<exclude>src/test/java/org/exist/xmldb/TreeLevelOrderTest.java</exclude>
13171319
<exclude>src/test/java/org/exist/xmldb/concurrent/XMLGenerator.java</exclude>

exist-core/src/main/java/org/exist/xmldb/LocalXMLResource.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,11 @@ else if (root != null && !(root instanceof NodeValue)) {
159159
} else if (value != null) {
160160
try {
161161
if (Type.subTypeOf(value.getType(),Type.STRING)) {
162-
return ((StringValue)value).getStringValue(true);
162+
return ((StringValue) value).getStringValue(true);
163+
164+
} else if (Type.subTypeOf(value.getType(), Type.MAP_ITEM) || Type.subTypeOf(value.getType(), Type.ARRAY_ITEM)) {
165+
return value.toString();
166+
163167
} else {
164168
return value.getStringValue();
165169
}

exist-core/src/main/java/org/exist/xmlrpc/RpcConnection.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1845,6 +1845,10 @@ private Map<String, Object> queryResultToRpcResponse(final long startTime, final
18451845
entry.add(String.valueOf(((NodeImpl) next).getNodeNumber()));
18461846
}
18471847
result.add(entry);
1848+
1849+
} else if (Type.subTypeOf(next.getType(), Type.MAP_ITEM) || Type.subTypeOf(next.getType(), Type.ARRAY_ITEM)) {
1850+
result.add(next.toString());
1851+
18481852
} else {
18491853
result.add(next.getStringValue());
18501854
}
@@ -2009,7 +2013,14 @@ private Map<String, String> atomicMap(final Item item) throws XPathException {
20092013

20102014
final int type = item.getType();
20112015
result.put("type", Type.getTypeName(type));
2012-
result.put("value", item.getStringValue());
2016+
2017+
final String value;
2018+
if (Type.subTypeOf(item.getType(), Type.MAP_ITEM) || Type.subTypeOf(item.getType(), Type.ARRAY_ITEM)) {
2019+
value = item.toString();
2020+
} else {
2021+
value = item.getStringValue();
2022+
}
2023+
result.put("value", value);
20132024

20142025
return result;
20152026
}

exist-core/src/main/java/org/exist/xquery/functions/array/ArrayType.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,11 +489,37 @@ public String toString() {
489489
builder.append(' ');
490490
}
491491
for (int i = 0; i < vector.length(); i++) {
492-
final Sequence value = vector.nth(i);
493-
builder.append(value.toString());
494-
if (i < vector.length() - 1) {
492+
493+
if (i > 0) {
495494
builder.append(", ");
496495
}
496+
497+
final Sequence sequence = vector.nth(i);
498+
499+
if (!sequence.hasOne()) {
500+
builder.append('(');
501+
}
502+
503+
for (int j = 0; j < sequence.getItemCount(); j++) {
504+
if (j > 0) {
505+
builder.append(", ");
506+
}
507+
508+
final Item item = sequence.itemAt(j);
509+
if (Type.subTypeOf(item.getType(), Type.STRING)) {
510+
builder.append('"');
511+
}
512+
513+
builder.append(item.toString());
514+
515+
if (Type.subTypeOf(item.getType(), Type.STRING)) {
516+
builder.append('"');
517+
}
518+
}
519+
520+
if (!sequence.hasOne()) {
521+
builder.append(')');
522+
}
497523
}
498524
if (vector.length() > 0) {
499525
builder.append(' ');

exist-core/src/test/java/org/exist/xmldb/SerializationTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*
21+
* NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
* The original license header is included below.
23+
*
24+
* =====================================================================
25+
*
226
* eXist-db Open Source Native XML Database
327
* Copyright (C) 2001 The eXist-db Authors
428
*
@@ -242,6 +266,30 @@ public void getXmlDeclYes() throws XMLDBException {
242266
}
243267
}
244268

269+
@Test
270+
public void testArray() throws XMLDBException {
271+
final String query = "array { \"value 1\", \"value 2\" }";
272+
273+
final XQueryService service = testCollection.getService(XQueryService.class);
274+
final ResourceSet result = service.query(query);
275+
assertEquals(1, result.getSize());
276+
277+
final Resource resource = result.getResource(0);
278+
assertEquals("[ \"value 1\", \"value 2\" ]", resource.getContent());
279+
}
280+
281+
@Test
282+
public void testMap() throws XMLDBException {
283+
final String query = "map { \"prop1\" : \"value 1\", \"prop2\" : \"value 2\" }";
284+
285+
final XQueryService service = testCollection.getService(XQueryService.class);
286+
final ResourceSet result = service.query(query);
287+
assertEquals(1, result.getSize());
288+
289+
final Resource resource = result.getResource(0);
290+
assertEquals("map {\"prop2\": \"value 2\", \"prop1\": \"value 1\"}", resource.getContent());
291+
}
292+
245293
private static void assertXMLEquals(final String expected, final Resource actual) throws XMLDBException {
246294
final Source srcExpected = Input.fromString(expected).build();
247295
final Source srcActual = Input.fromString(actual.getContent().toString()).build();

0 commit comments

Comments
 (0)