Till Westmann has proposed merging lp:~zorba-coders/zorba/fix-fn-path into 
lp:zorba.

Requested reviews:
  Ghislain Fourny (gislenius)
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/fix-fn-path/+merge/114739

fix position for elements and processing-instructions in fn:path
-- 
https://code.launchpad.net/~zorba-coders/zorba/fix-fn-path/+merge/114739
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-12 21:21:38 +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 += "\""+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 += "\""+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 = "\"http://www.w3.org/2005/xpath-functions\":root()";
+      path += temp;
+    }
+
+    STACK_PUSH(GENV_ITEMFACTORY->createString(result, path), state);
   }
 
   STACK_END (state);

-- 
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

Reply via email to