|
45 | 45 | */ |
46 | 46 | package org.exist.xqj; |
47 | 47 |
|
| 48 | +import com.evolvedbinary.j8fu.tuple.Tuple2; |
48 | 49 | import org.exist.dom.QName; |
49 | 50 | import org.exist.dom.memtree.*; |
50 | 51 | import org.exist.storage.DBBroker; |
|
54 | 55 | import org.exist.xquery.XPathException; |
55 | 56 | import org.exist.xquery.XQueryContext; |
56 | 57 | import org.exist.xquery.functions.array.ArrayType; |
| 58 | +import org.exist.xquery.functions.map.MapType; |
57 | 59 | import org.exist.xquery.value.*; |
58 | 60 | import org.w3c.dom.Comment; |
59 | 61 | import org.w3c.dom.Document; |
60 | 62 | import org.w3c.dom.Element; |
61 | 63 | import org.w3c.dom.Node; |
| 64 | +import org.w3c.dom.NodeList; |
62 | 65 | import org.w3c.dom.ProcessingInstruction; |
63 | 66 | import org.w3c.dom.Text; |
64 | 67 | import org.xml.sax.ContentHandler; |
|
80 | 83 | import java.util.List; |
81 | 84 | import java.util.Properties; |
82 | 85 |
|
| 86 | +import static com.evolvedbinary.j8fu.tuple.Tuple.Tuple; |
83 | 87 | import static org.exist.util.StringUtil.nullIfEmpty; |
84 | 88 |
|
85 | 89 |
|
@@ -111,6 +115,8 @@ public class Marshaller { |
111 | 115 | private final static String ATTR_NAME = "name"; |
112 | 116 |
|
113 | 117 | public final static QName SEQUENCE_ELEMENT_QNAME = new QName(SEQ_ELEMENT, NAMESPACE, PREFIX); |
| 118 | + public final static QName ENTRY_ELEMENT_QNAME = new QName("entry", NAMESPACE, PREFIX); |
| 119 | + public final static QName KEY_ELEMENT_QNAME = new QName("key", NAMESPACE, PREFIX); |
114 | 120 |
|
115 | 121 | /** |
116 | 122 | * Marshall a sequence in an xml based string representation. |
@@ -300,6 +306,9 @@ private static Item demarshallValue(final XQueryContext context, final ElementIm |
300 | 306 | final InMemoryNodeSet sxSequences = new InMemoryNodeSet(); |
301 | 307 | sxValue.selectChildren(new NameTest(Type.ELEMENT, SEQUENCE_ELEMENT_QNAME), sxSequences); |
302 | 308 |
|
| 309 | + final InMemoryNodeSet sxEntries = new InMemoryNodeSet(); |
| 310 | + sxValue.selectChildren(new NameTest(Type.ELEMENT, ENTRY_ELEMENT_QNAME), sxEntries); |
| 311 | + |
303 | 312 | Node item = sxValue.getFirstChild(); |
304 | 313 |
|
305 | 314 | if (type == Type.ATTRIBUTE || (type == Type.ITEM && attrNameString != null)) { |
@@ -393,6 +402,24 @@ private static Item demarshallValue(final XQueryContext context, final ElementIm |
393 | 402 | } |
394 | 403 | return new ArrayType(context, arrayValues); |
395 | 404 |
|
| 405 | + } else if (type == Type.MAP_ITEM || (type == Type.ITEM && !sxEntries.isEmpty())) { |
| 406 | + // map(*) type |
| 407 | + final List<Tuple2<AtomicValue, Sequence>> mapEntries = new ArrayList<>(); |
| 408 | + |
| 409 | + for (final SequenceIterator itSxEntry = sxEntries.iterate(); itSxEntry.hasNext();) { |
| 410 | + final ElementImpl sxEntry = (ElementImpl) itSxEntry.nextItem(); |
| 411 | + final NodeList entryKeys = sxEntry.getElementsByTagNameNS(KEY_ELEMENT_QNAME.getNamespaceURI(), KEY_ELEMENT_QNAME.getLocalPart()); |
| 412 | + final Element entryKey = (Element) entryKeys.item(0); |
| 413 | + final int keyType = Type.getType(entryKey.getAttribute(ATTR_TYPE)); |
| 414 | + final String keyStr = entryKey.getTextContent(); |
| 415 | + final AtomicValue key = new StringValue(keyStr).convertTo(keyType); |
| 416 | + final NodeList entrySequences = sxEntry.getElementsByTagNameNS(SEQUENCE_ELEMENT_QNAME.getNamespaceURI(), SEQUENCE_ELEMENT_QNAME.getLocalPart()); |
| 417 | + final ElementImpl entrySequence = (ElementImpl) entrySequences.item(0); |
| 418 | + final Sequence value = demarshallSequence(context, entrySequence); |
| 419 | + mapEntries.add(Tuple(key, value)); |
| 420 | + } |
| 421 | + return new MapType(context, null, mapEntries); |
| 422 | + |
396 | 423 | } else { |
397 | 424 | // specific non-node type or text() |
398 | 425 | final StringBuilder data = new StringBuilder(); |
|
0 commit comments