5252import org .exist .xquery .NameTest ;
5353import org .exist .xquery .XPathException ;
5454import org .exist .xquery .value .*;
55+ import org .w3c .dom .Attr ;
56+ import org .w3c .dom .Comment ;
57+ import org .w3c .dom .Document ;
5558import org .w3c .dom .Element ;
5659import org .w3c .dom .Node ;
60+ import org .w3c .dom .ProcessingInstruction ;
61+ import org .w3c .dom .Text ;
5762import org .xml .sax .ContentHandler ;
5863import org .xml .sax .SAXException ;
5964import org .xml .sax .helpers .AttributesImpl ;
@@ -242,7 +247,7 @@ public static Sequence demarshall(DBBroker broker, XMLStreamReader parser) throw
242247 return result ;
243248 }
244249
245- public static Sequence demarshall (NodeImpl node ) throws XMLStreamException , XPathException {
250+ public static Sequence demarshall (final NodeImpl node ) throws XMLStreamException , XPathException {
246251 final String ns = node .getNamespaceURI ();
247252 if (ns == null || !NAMESPACE .equals (ns )) {
248253 throw new XMLStreamException ("Root element is not in the correct namespace. Expected: " + NAMESPACE );
@@ -262,41 +267,84 @@ public static Sequence demarshall(NodeImpl node) throws XMLStreamException, XPat
262267 type = Type .getType (typeName );
263268 }
264269
265- Item item ;
270+ Node item = sxValue . getFirstChild () ;
266271 if (Type .subTypeOf (type , Type .NODE )) {
267- item = (Item ) sxValue .getFirstChild ();
268- if (type == Type .DOCUMENT ) {
269- final DocumentImpl n = (DocumentImpl ) item ;
270- final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver (n .getExpression ());
271- try {
272- receiver .startDocument ();
273- n .copyTo (n , receiver );
274- receiver .endDocument ();
275- } catch (final SAXException e ) {
276- throw new XPathException (item != null ? item .getExpression () : null , "Error while demarshalling node: " + e .getMessage (), e );
277- }
278- item = (Item ) receiver .getDocument ();
279- }
280- } else {
281- final StringBuilder data = new StringBuilder ();
282- Node value = sxValue .getFirstChild ();
283272
284- if (value instanceof Element && type == Type .ITEM ) {
285- item = (NodeImpl ) value ;
273+ switch (type ) {
274+ case Type .ELEMENT :
275+ if (item instanceof Document ) {
276+ result .add ((ElementImpl ) ((DocumentImpl ) item ).getDocumentElement ());
277+ } else if (!(item instanceof Element )) {
278+ throw new XMLStreamException ("sx:value should only contain an Element if type is " + typeName );
279+ } else {
280+ result .add ((ElementImpl ) item );
281+ }
282+ break ;
283+
284+ case Type .ATTRIBUTE :
285+ if (!(item instanceof Attr )) {
286+ throw new XMLStreamException ("sx:value should only contain an Attribute if type is " + typeName );
287+ }
288+ result .add ((AttrImpl ) item );
289+ break ;
290+
291+ case Type .COMMENT :
292+ if (!(item instanceof Comment )) {
293+ throw new XMLStreamException ("sx:value should only contain a Comment node if type is " + typeName );
294+ }
295+ result .add ((CommentImpl ) item );
296+ break ;
297+
298+ case Type .PROCESSING_INSTRUCTION :
299+ if (!(item instanceof ProcessingInstruction )) {
300+ throw new XMLStreamException ("sx:value should only contain a Processing Instruction node if type is " + typeName );
301+ }
302+ result .add ((ProcessingInstructionImpl ) item );
303+ break ;
304+
305+ case Type .TEXT :
306+ if (!(item instanceof Text )) {
307+ throw new XMLStreamException ("sx:value should only contain a Text node if type is " + typeName );
308+ }
309+ result .add ((TextImpl ) item );
310+ break ;
286311
287- } else {
288- while (value != null ) {
289- if (!(value .getNodeType () == Node .TEXT_NODE || value .getNodeType () == Node .CDATA_SECTION_NODE )) {
290- throw new XMLStreamException ("sx:value should only contain text if type is " + typeName );
312+ case Type .DOCUMENT :
313+ default :
314+ if (item instanceof Document || item instanceof Element ) {
315+ final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver (((NodeImpl ) item ).getExpression ());
316+ try {
317+ receiver .startDocument ();
318+ ((NodeImpl ) item ).copyTo (null , receiver );
319+ receiver .endDocument ();
320+ } catch (final SAXException e ) {
321+ throw new XPathException (item != null ? ((NodeImpl ) item ).getExpression () : null , "Error while demarshalling node: " + e .getMessage (), e );
322+ }
323+ result .add ((NodeImpl ) receiver .getDocument ());
324+ } else {
325+ throw new XMLStreamException ("sx:value should only contain a Node if type is " + typeName );
291326 }
292- data .append (value .getNodeValue ());
293- value = value .getNextSibling ();
327+ break ;
328+ }
329+
330+ } else if (type == Type .ITEM && !(item instanceof Text )) {
331+ // item() type requested and we have been given a node which is not a text() node
332+ result .add ((NodeImpl ) item );
333+
334+ } else {
335+ // specific non-node type or text()
336+ final StringBuilder data = new StringBuilder ();
337+ while (item != null ) {
338+ if (!(item .getNodeType () == Node .TEXT_NODE || item .getNodeType () == Node .CDATA_SECTION_NODE )) {
339+ throw new XMLStreamException ("sx:value should only contain text if type is " + typeName );
294340 }
295- item = new StringValue (data .toString ()).convertTo (type );
341+ data .append (item .getNodeValue ());
342+ item = item .getNextSibling ();
296343 }
344+ result .add (new StringValue (data .toString ()).convertTo (type ));
297345 }
298- result .add (item );
299346 }
347+
300348 return result ;
301349 }
302350
0 commit comments