Till Westmann has proposed merging lp:~zorba-coders/zorba/fix-fn-path into lp:zorba.
Requested reviews: Matthias Brantner (matthias-brantner) Markos Zaharioudakis (markos-za) Related bugs: Bug #1024123 in Zorba: "Un-revert r10899" https://bugs.launchpad.net/zorba/+bug/1024123 Bug #1024279 in Zorba: "fn:path seg faults" https://bugs.launchpad.net/zorba/+bug/1024279 For more details, see: https://code.launchpad.net/~zorba-coders/zorba/fix-fn-path/+merge/114922 fix position for elements and processing-instructions in fn:path -- https://code.launchpad.net/~zorba-coders/zorba/fix-fn-path/+merge/114922 Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/runtime/nodes/nodes_impl.cpp' --- src/runtime/nodes/nodes_impl.cpp 2012-07-12 17:29:55 +0000 +++ src/runtime/nodes/nodes_impl.cpp 2012-07-13 18:59:22 +0000 @@ -680,7 +680,7 @@ /******************************************************************************* ********************************************************************************/ -int getNodePosition(store::Item_t aNode) +int getNodePosition(store::Item_t aNode, store::Item_t aNodeName) { int count = 1; store::Iterator_t lIterator = aNode->getParent()->getChildren(); @@ -692,7 +692,7 @@ { if(lItem->equals(aNode)) break; - else + else if (aNodeName.isNull() || aNodeName->equals(lItem->getNodeName())) count++; } } @@ -703,101 +703,87 @@ bool FnPathIterator::nextImpl(store::Item_t& result, PlanState& planState) const { store::Item_t inNode; + store::Item_t swap; store::Item_t nodeName; - store::NsBindings nsBindings; zstring path; zstring temp; zstring zNamespace; zstring zLocalName; zstring zPosition; - bool rootIsDocument = false; PlanIteratorState* state; DEFAULT_STACK_INIT(PlanIteratorState, state, planState); if (consumeNext(inNode, theChildren[0], planState)) { - do - { + while (inNode->getParent()) + { + temp = path; + path = "/"; + switch (inNode->getNodeKind()) { - case store::StoreConsts::documentNode: - temp = path; - path = "/"; - path += temp; - rootIsDocument = true; - break; - case store::StoreConsts::elementNode: nodeName = inNode->getNodeName(); zNamespace = nodeName->getNamespace(); zLocalName = nodeName->getLocalName(); - zPosition = ztd::to_string(getNodePosition(inNode)); - temp = path; - path = "Q{"+zNamespace+"}"+zLocalName+"["+zPosition.c_str()+"]"; - path += temp; + zPosition = ztd::to_string(getNodePosition(inNode, nodeName)); + path += "Q{" + zNamespace + "}" + zLocalName + "[" + zPosition + "]"; break; - case store::StoreConsts::attributeNode: nodeName = inNode->getNodeName(); zNamespace =nodeName->getNamespace(); zLocalName = nodeName->getLocalName(); + path += "@"; if(zNamespace != "") { - temp = path; - path = "@Q{"+zNamespace+"}"+zLocalName; - path += temp; - } - else - { - temp = path; - path = "@"+zLocalName; - path += temp; - } + path += "Q{" + zNamespace + "}"; + } + path += zLocalName; break; - case store::StoreConsts::textNode: - zPosition = ztd::to_string(getNodePosition(inNode)); - temp = path; - path = "text()["+zPosition+"]"; - path += temp; + zPosition = ztd::to_string(getNodePosition(inNode, NULL)); + path += "text()[" + zPosition + "]"; break; - case store::StoreConsts::commentNode: - zPosition = ztd::to_string(getNodePosition(inNode)); - temp = path; - path = "comment()["+zPosition+"]"; - path += temp; + zPosition = ztd::to_string(getNodePosition(inNode, NULL)); + path += "comment()[" + zPosition + "]"; break; - - case store::StoreConsts::piNode: + case store::StoreConsts::piNode: nodeName = inNode->getNodeName(); zLocalName = nodeName->getLocalName(); - zPosition = ztd::to_string(getNodePosition(inNode)); - temp = path; - path = "processing-instruction("+zLocalName+")["+zPosition+"]"; - path += temp; + zPosition = ztd::to_string(getNodePosition(inNode, nodeName)); + path += "processing-instruction(" + zLocalName + ")[" + zPosition + "]"; break; - default: + // this is either a documentNode which should always be a root + // node (and not end up here) or it is something very strange ZORBA_ASSERT(false); + break; } - - inNode = inNode->getParent(); - - if (inNode && inNode->getNodeKind() != store::StoreConsts::documentNode) + path += temp; + + swap = inNode->getParent(); + inNode = swap; + } + + // only the root node is left and there we've got some special + // cases in the spec + if (inNode->getNodeKind() == store::StoreConsts::documentNode) + { + if (path.empty()) { - temp = path; path = "/"; - path += temp; } - - } while (inNode); - - if(rootIsDocument) - STACK_PUSH(GENV_ITEMFACTORY->createString(result, path), state); + } else - throw XQUERY_EXCEPTION(err::FODC0001, ERROR_PARAMS("fn:path"), ERROR_LOC(loc)); + { + temp = path; + path = "Q{http://www.w3.org/2005/xpath-functions}root()"; + path += temp; + } + + STACK_PUSH(GENV_ITEMFACTORY->createString(result, path), state); } STACK_END (state); === added file 'test/rbkt/ExpQueryResults/zorba/nodes/path.xml.res' --- test/rbkt/ExpQueryResults/zorba/nodes/path.xml.res 1970-01-01 00:00:00 +0000 +++ test/rbkt/ExpQueryResults/zorba/nodes/path.xml.res 2012-07-13 18:59:22 +0000 @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +/Q{some-namespace}doc[1] Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[2] Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[2]/Q{}c[1]/@d Q{http://www.w3.org/2005/xpath-functions}root()/Q{some-namespace}e[1]/@Q{some-namespace}f === added file 'test/rbkt/Queries/zorba/nodes/path.xq' --- test/rbkt/Queries/zorba/nodes/path.xq 1970-01-01 00:00:00 +0000 +++ test/rbkt/Queries/zorba/nodes/path.xq 2012-07-13 18:59:22 +0000 @@ -0,0 +1,9 @@ +declare namespace ns = "some-namespace"; + +let $doc := document { <ns:doc/> }/*:doc, + $a := <a><b/><b><c d="e"/></b><ns:e ns:f="g"/></a>, + $b := $a/b[c], + $d := $a/b/c/@d, + $f := $a//@ns:f +return + ( path($doc), path($b), path($d), path($f) )
-- Mailing list: https://launchpad.net/~zorba-coders Post to : zorba-coders@lists.launchpad.net Unsubscribe : https://launchpad.net/~zorba-coders More help : https://help.launchpad.net/ListHelp