← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/bug-1055608-node-kinds-for-roundtrip into lp:zorba

 

Till Westmann has proposed merging lp:~zorba-coders/zorba/bug-1055608-node-kinds-for-roundtrip into lp:zorba.

Commit message:
use XDM node kinds in encode-for-roundtrip

Requested reviews:
  Matthias Brantner (matthias-brantner)
  Ghislain Fourny (gislenius)
Related bugs:
  Bug #1055608 in Zorba: "use XDM node kinds in encode-for-roundtrip"
  https://bugs.launchpad.net/zorba/+bug/1055608

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-1055608-node-kinds-for-roundtrip/+merge/126590

use XDM node kinds in encode-for-roundtrip
-- 
https://code.launchpad.net/~zorba-coders/zorba/bug-1055608-node-kinds-for-roundtrip/+merge/126590
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/runtime/json/jsoniq_functions_impl.cpp'
--- src/runtime/json/jsoniq_functions_impl.cpp	2012-09-24 17:11:12 +0000
+++ src/runtime/json/jsoniq_functions_impl.cpp	2012-09-27 02:16:25 +0000
@@ -67,6 +67,72 @@
 const char * OPTIONS_KEY_PREFIX = "prefix";
 const char * OPTIONS_KEY_SER_PARAMS = "serialization-parameters";
 
+const char * SEQTYPE_ANYNODE  = "node()";
+const char * SEQTYPE_COMMENT  = "comment()";
+const char * SEQTYPE_DOCUMENT = "document-node()";
+const char * SEQTYPE_ELEMENT  = "element()";
+const char * SEQTYPE_PROCINST = "processing-instruction()";
+const char * SEQTYPE_TEXT     = "text()";
+
+const char * kind2str(const store::NodeKind& aKind)
+{
+  // we do not support attibutes and namespaces as they cannot be serialized
+  switch (aKind)
+  {
+  case store::StoreConsts::anyNode:      return SEQTYPE_ANYNODE;
+  case store::StoreConsts::commentNode:  return SEQTYPE_COMMENT;
+  case store::StoreConsts::documentNode: return SEQTYPE_DOCUMENT;
+  case store::StoreConsts::elementNode:  return SEQTYPE_ELEMENT;
+  case store::StoreConsts::piNode:       return SEQTYPE_PROCINST;
+  case store::StoreConsts::textNode:     return SEQTYPE_TEXT;
+  default: return "";
+  }
+}
+
+bool str2kind(const zstring& aString, store::NodeKind& aKind)
+{
+  switch(aString.at(0))
+  {
+  case 'c':
+    if (aString == SEQTYPE_COMMENT)
+    {
+      aKind = store::StoreConsts::commentNode;
+      return true;
+    }
+    break;
+  case 'd':
+    if (aString == SEQTYPE_DOCUMENT)
+    {
+      aKind = store::StoreConsts::documentNode;
+      return true;
+    }
+    break;
+  case 'e':
+  case 'n': // "node()" maps to element for backwards compatibility
+    if (aString == SEQTYPE_ELEMENT || aString == SEQTYPE_ANYNODE)
+    {
+      aKind = store::StoreConsts::elementNode;
+      return true;
+    }
+    break;
+  case 'p':
+    if (aString == SEQTYPE_PROCINST)
+    {
+      aKind = store::StoreConsts::piNode;
+      return true;
+    }
+    break;
+  case 't':
+    if (aString == SEQTYPE_TEXT)
+    {
+      aKind = store::StoreConsts::textNode;
+      return true;
+    }
+    break;
+  }
+  return false;
+}
+
 /*******************************************************************************
   json:decode-from-roundtrip($items as json-item()*,
                              $options as object()) as structured-item()*
@@ -125,32 +191,75 @@
 
   zstring lTypeNameString;
   lTypeValueItem->getStringValue2(lTypeNameString);
-  if (lTypeNameString == "node()")
+  store::NodeKind lNodeKind;
+  if (str2kind(lTypeNameString, lNodeKind))
   {
     store::LoadProperties lProperties;
     lProperties.setStoreDocument(false);
     store::Item_t lDoc;
-    if (lValueValueItem->isStreamable())
-    {
-      lDoc = GENV.getStore().loadDocument(
-            "", "", lValueValueItem->getStream(), lProperties);
+    zstring lXmlString;
+    switch (lNodeKind)
+    {
+    case store::StoreConsts::commentNode:
+    case store::StoreConsts::piNode:
+    case store::StoreConsts::textNode:
+      {
+        // we have to wrap these 3 node kinds, so we cannot care about streams
+        lValueValueItem->getStringValue2(lXmlString);
+        lXmlString = "<a>" + lXmlString + "</a>";
+        std::istringstream lStream(lXmlString.c_str());
+        lDoc = GENV.getStore().loadDocument("", "", lStream, lProperties);
+      }
+      break;
+    default:
+      if (lValueValueItem->isStreamable())
+      {
+        lDoc = GENV.getStore().loadDocument(
+              "", "", lValueValueItem->getStream(), lProperties);
+      }
+      else
+      {
+        lValueValueItem->getStringValue2(lXmlString);
+        std::istringstream lStream(lXmlString.c_str());
+        lDoc = GENV.getStore().loadDocument("", "", lStream, lProperties);
+      }
+      break;
+    }
+    if (lNodeKind == store::StoreConsts::documentNode)
+    {
+      aResult = lDoc;
     }
     else
     {
-      zstring lXmlString;
-      lValueValueItem->getStringValue2(lXmlString);
-      std::istringstream lStream(lXmlString.c_str());
-      lDoc = GENV.getStore().loadDocument("", "", lStream, lProperties);
-    }
-    store::Iterator_t lIt = lDoc->getChildren();
-    bool lFound = false;
-    lIt->open();
-    while (! lFound && lIt->next(aResult))
-    {
-       lFound = aResult->getNodeKind() == store::StoreConsts::elementNode;
-    }
-    lIt->close();
-    ZORBA_ASSERT(lFound);
+      store::Item_t lRootElem;
+      store::Iterator_t lIt = lDoc->getChildren();
+      bool lFound = false;
+      lIt->open();
+      while (! lFound && lIt->next(lRootElem))
+      {
+        lFound = lRootElem->getNodeKind() == store::StoreConsts::elementNode;
+      }
+      lIt->close();
+      ZORBA_ASSERT(lFound);
+      if (lNodeKind == store::StoreConsts::elementNode)
+      {
+        // if we needed an element we're done
+        aResult = lRootElem;
+      }
+      else
+      {
+        // otherwise we have to pass through the wrapper that we've created
+        store::Iterator_t lIt = lRootElem->getChildren();
+        bool lFound = false;
+        lIt->open();
+        while (! lFound && lIt->next(aResult))
+        {
+          lFound = aResult->getNodeKind() == lNodeKind;
+        }
+        lIt->close();
+        ZORBA_ASSERT(lFound);
+      }
+    }
   }
   else
   {
@@ -478,23 +587,12 @@
     store::Item_t& aResult,
     JSONEncodeForRoundtripIteratorState* aState) const
 {
-  if (aNode->getNodeKind() != store::StoreConsts::elementNode)
-  {
-    // this is a temporary solution until we decide if/how we encode
-    // node kinds
-    RAISE_ERROR(
-      zerr::ZXQP0004_NOT_IMPLEMENTED,
-      loc,
-      ERROR_PARAMS(store::StoreConsts::toString(aNode->getNodeKind()))
-    );
-  }
-
   std::vector<store::Item_t> names(2);
   std::vector<store::Item_t> values(2);
 
   {
     zstring typeKey = aState->thePrefix + TYPE_KEY;
-    zstring typeValue = "node()";
+    zstring typeValue = kind2str(aNode->getNodeKind());
     GENV_ITEMFACTORY->createString(names.at(0), typeKey);
     GENV_ITEMFACTORY->createString(values.at(0), typeValue);
   }

=== modified file 'test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/encode_03.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/encode_03.xml.res	2012-09-13 21:35:10 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/encode_03.xml.res	2012-09-27 02:16:25 +0000
@@ -1,1 +1,1 @@
-{ "serialized XML" : { "Q{http://jsoniq.org/roundtrip}type"; : "node()", "Q{http://jsoniq.org/roundtrip}value"; : "<para>\n         A pair named \"[$prefix]value\" (where [$prefix] is replaced with the\n         value of the parameter $prefix) and whose value is a serialization\n         of the XML node according to the XML output method and with the\n         serialization parameters specified by $param.\n         </para>" } }
\ No newline at end of file
+{ "serialized XML" : { "Q{http://jsoniq.org/roundtrip}type"; : "element()", "Q{http://jsoniq.org/roundtrip}value"; : "<para>\n         A pair named \"[$prefix]value\" (where [$prefix] is replaced with the\n         value of the parameter $prefix) and whose value is a serialization\n         of the XML node according to the XML output method and with the\n         serialization parameters specified by $param.\n         </para>" } }

=== modified file 'test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/encode_04.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/encode_04.xml.res	2012-09-13 21:40:53 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/encode_04.xml.res	2012-09-27 02:16:25 +0000
@@ -1,1 +1,1 @@
-{ "serialized XML" : { "pre-type" : "node()", "pre-value" : "<a>\n  <b>text<c>more text</c>\n  </b>\n</a>" } }
\ No newline at end of file
+{ "serialized XML" : { "pre-type" : "element()", "pre-value" : "<a>\n  <b>text<c>more text</c>\n  </b>\n</a>" } }

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/encode_10.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/encode_10.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/encode_10.xml.res	2012-09-27 02:16:25 +0000
@@ -0,0 +1,1 @@
+{ "comment" : { "Q{http://jsoniq.org/roundtrip}type"; : "comment()", "Q{http://jsoniq.org/roundtrip}value"; : "<!--a comment-->" }, "document" : { "Q{http://jsoniq.org/roundtrip}type"; : "document-node()", "Q{http://jsoniq.org/roundtrip}value"; : "<a/>" }, "pi" : { "Q{http://jsoniq.org/roundtrip}type"; : "processing-instruction()", "Q{http://jsoniq.org/roundtrip}value"; : "<?target an instauction?>" }, "text" : { "Q{http://jsoniq.org/roundtrip}type"; : "text()", "Q{http://jsoniq.org/roundtrip}value"; : "some text" } }

=== modified file 'test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/roundtrip_03.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/roundtrip_03.xml.res	2012-09-20 17:44:15 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/roundtrip_03.xml.res	2012-09-27 02:16:25 +0000
@@ -1,1 +1,1 @@
-{ "foo" : { "Q{http://jsoniq.org/roundtrip}type"; : "node()", "Q{http://jsoniq.org/roundtrip}value"; : "<a id=\"bar\"/>" } }
+{ "foo" : { "Q{http://jsoniq.org/roundtrip}type"; : "element()", "Q{http://jsoniq.org/roundtrip}value"; : "<a id=\"bar\"/>" } }

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/roundtrip_06.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/roundtrip_06.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/roundtrip/roundtrip_06.xml.res	2012-09-27 02:16:25 +0000
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+true true true true

=== added file 'test/rbkt/Queries/zorba/jsoniq/roundtrip/encode_10.xq'
--- test/rbkt/Queries/zorba/jsoniq/roundtrip/encode_10.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/roundtrip/encode_10.xq	2012-09-27 02:16:25 +0000
@@ -0,0 +1,8 @@
+jn:encode-for-roundtrip(
+  {
+    'comment' : comment { "a comment" },
+    'document' : document { <a/> },
+    'pi' : processing-instruction target { "an instauction" },
+    'text' : text { "some text" }
+  }
+)

=== added file 'test/rbkt/Queries/zorba/jsoniq/roundtrip/roundtrip_06.xq'
--- test/rbkt/Queries/zorba/jsoniq/roundtrip/roundtrip_06.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/roundtrip/roundtrip_06.xq	2012-09-27 02:16:25 +0000
@@ -0,0 +1,15 @@
+let $enc := jn:encode-for-roundtrip(
+    {
+      'comment' : comment { "a comment" },
+      'document' : document { <a/> } ,
+      'pi' : processing-instruction target { "an instauction" },
+      'text' : text { "some text" }
+    }
+  )
+let $dec := jn:decode-from-roundtrip($enc)
+return (
+  $dec("comment") instance of comment(),
+  $dec("document") instance of document-node(),
+  $dec("pi") instance of processing-instruction(),
+  $dec("text") instance of text()
+)


Follow ups