diff --git a/src/org/exist/dom/persistent/ElementImpl.java b/src/org/exist/dom/persistent/ElementImpl.java index 21656ee77d8..aa61443999d 100644 --- a/src/org/exist/dom/persistent/ElementImpl.java +++ b/src/org/exist/dom/persistent/ElementImpl.java @@ -88,8 +88,8 @@ public class ElementImpl extends NamedNode implements Element { public static final int LENGTH_NS_ID = 2; //sizeof short public static final int LENGTH_PREFIX_LENGTH = 2; //sizeof short - private short attributes = 0; - private int children = 0; + private short attributes = 0; // number of attributes + private int children = 0; // number of elements AND attributes private int position = 0; private Map namespaceMappings = null; @@ -583,7 +583,7 @@ public void appendChildren(final Txn transaction, NodeList nodes, final int chil final IStoredNode last = (IStoredNode) cl.item(child - 2); insertAfter(transaction, nodes, last); } else { - final IStoredNode last = (IStoredNode) getLastChild(); + final IStoredNode last = (IStoredNode) getLastChild(true); appendChildren(transaction, last.getNodeId().nextSibling(), null, new NodeImplRef(getLastNode(last)), path, nodes, listener); } @@ -1030,16 +1030,41 @@ public Node getFirstChild() { @Override public Node getLastChild() { - if(!hasChildNodes()) { + return getLastChild(false); + } + + /** + * Get the last child. + * + * @param attributesAreChildren In the DLN model attributes have child node ids, + * however in the DOM model attributes are not child nodes. Set true for DLN + * or false for DOM. + * + * @return the last child. + */ + private Node getLastChild(final boolean attributesAreChildren) { + if ((!attributesAreChildren) && (!hasChildNodes())) { + // DOM model + return null; + } else if (!(hasChildNodes() || hasAttributes())) { + // DLN model return null; } + Node node = null; - if(!isDirty) { + if (!isDirty) { final NodeId child = nodeId.getChild(children); node = ownerDocument.getNode(new NodeProxy(ownerDocument, child)); } - if(node == null) { - final NodeList cl = getChildNodes(); + if (node == null) { + final NodeList cl; + if (!attributesAreChildren) { + // DOM model + cl = getChildNodes(); + } else { + // DLN model + cl = getAttrsAndChildNodes(); + } return cl.item(cl.getLength() - 1); } return node; diff --git a/test/src/xquery/suite.xql b/test/src/xquery/suite.xql index 4a94cb24725..8337e3afac6 100644 --- a/test/src/xquery/suite.xql +++ b/test/src/xquery/suite.xql @@ -15,5 +15,6 @@ test:suite(( inspect:module-functions(xs:anyURI("nill.xql")), inspect:module-functions(xs:anyURI("ft-match.xql")), inspect:module-functions(xs:anyURI("types.xql")), - inspect:module-functions(xs:anyURI("unparsed-text.xql")) + inspect:module-functions(xs:anyURI("unparsed-text.xql")), + inspect:module-functions(xs:anyURI("xquery-update.xql")) )) diff --git a/test/src/xquery/xquery-update.xql b/test/src/xquery/xquery-update.xql new file mode 100644 index 00000000000..4ec74c2d0b2 --- /dev/null +++ b/test/src/xquery/xquery-update.xql @@ -0,0 +1,57 @@ +xquery version "3.1"; + +module namespace xqu="http://exist-db.org/xquery/test/xquery-update"; + +import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; + + +declare + %test:assertEquals('') +function xqu:root() { + let $f := xmldb:store('/db', 'xupdate.xml', ) + let $u := update insert into doc($f)/root + return doc($f) +}; + +declare +%test:assertEquals('') +function xqu:root_attribute() { + let $r := xmldb:remove('/db', 'xupdate.xml') + let $f := xmldb:store('/db', 'xupdate.xml', ) + let $u := update insert into doc($f)/root + return doc($f) +}; + +declare +%test:assertEquals('') +function xqu:root_attribute_child() { + let $r := xmldb:remove('/db', 'xupdate.xml') + let $f := xmldb:store('/db', 'xupdate.xml', ) + let $u := update insert into doc($f)/root + return doc($f) +}; + +declare +%test:assertEquals('') +function xqu:root_attribute_child_attribute() { + let $r := xmldb:remove('/db', 'xupdate.xml') + let $f := xmldb:store('/db', 'xupdate.xml', ) + let $u := update insert into doc($f)/root + return doc($f) +}; + +declare +%test:assertEquals('') +function xqu:root_comment() { + let $f := xmldb:store('/db', 'xupdate.xml', ) + let $u := update insert into doc($f)/root + return doc($f) +}; + +declare +%test:assertEquals('') +function xqu:root_comment_attribute() { + let $f := xmldb:store('/db', 'xupdate.xml', ) + let $u := update insert into doc($f)/root + return doc($f) +};