Normalize xml processing
authorEduardo Ramos Testillano (eramedu) <eduardo.ramos.testillano@ericsson.com>
Sat, 2 May 2020 19:30:42 +0000 (21:30 +0200)
committerEduardo Ramos Testillano (eramedu) <eduardo.ramos.testillano@ericsson.com>
Sat, 2 May 2020 19:36:25 +0000 (21:36 +0200)
Centralize indentation spaces for xml representation with
 define macro 'ANNA_XML_INDENTATION_SPACES' which is 3.

Add new working mode for xml Compiler: Sort. This one will
sort attribute names within nodes. This eases normalization
to match regexps based on xml diameter messages representation.
As this mode is based on bit mask, must be power of 2 and the
next free is 8.

include/anna/core/util/defines.hpp
include/anna/xml/Compiler.hpp
include/anna/xml/Node.hpp
source/xml/Compiler.cpp

index 7e56b7d..25a7e03 100644 (file)
@@ -20,6 +20,9 @@
 // For cstd0x compatibility we will use stdint.h types instead of std:: ones on cstdint:
 //#include <cstdint>  when C++11 available
 
+// For xml representations (xml::Compiler and json::functions::json2xml)
+#define ANNA_XML_INDENTATION_SPACES 3
+
 
 // Decoding helpers
 #define DECODE2BYTES_INDX_VALUETYPE(buffer,indx,value_type) ((((value_type)buffer[indx] << 8) & 0xFF00) + ((value_type)buffer[indx+1] & 0x00FF))
index 581ba38..43e93ce 100644 (file)
@@ -13,8 +13,6 @@
 #include <anna/core/RuntimeException.hpp>
 #include <anna/core/mt/Mutex.hpp>
 
-// Three-space tabulator for xml string presentation (node indent)
-#define ANNA_XML_COMPILER_TAB  "   "
 
 namespace anna {
 
@@ -37,7 +35,8 @@ public:
       Visual = 0, /**< Separa cada uno de los componentes con espacios y retornos de carro */
       Compact = 1, /**< Los componentes no tienen separacion entre si. Se puede usar para optimizar envios de mensajes */
       ShowNullAttribute = 2, /**< Visualiza el valor nulo de un atributo como ="" */
-      NoNamespaces = 4 /**<Obtiene el documento XML sin ofrecer informaciĆ³n sobre los namespaces */
+      NoNamespaces = 4, /**<Obtiene el documento XML sin ofrecer informaciĆ³n sobre los namespaces */
+      Sort = 8, /** Sorts attribute names */
     };
   };
 
index a8579b7..7050a81 100644 (file)
@@ -458,10 +458,15 @@ private:
 
   static const Attribute* find(const char* attrName, const_attribute_iterator, const_attribute_iterator) throw();
 
+  // Allow sort in compiler
+  attribute_iterator attribute_begin() throw() { return a_attributes.begin(); }
+  attribute_iterator attribute_end() throw() { return a_attributes.end(); }
+
   friend class Parser;
   friend class Allocator<Node>;
   friend class XPath;
   friend class Decompressor;
+  friend class Compiler;
 };
 
 }
index 483e86e..1cbc286 100644 (file)
@@ -7,6 +7,7 @@
 
 
 #include <anna/core/mt/Guard.hpp>
+#include <anna/core/util/defines.hpp>
 
 #include <anna/xml/Compiler.hpp>
 #include <anna/xml/Node.hpp>
 #include <anna/xml/Document.hpp>
 #include <anna/xml/Namespace.hpp>
 
+#include <algorithm>
+#include <cstring>
+
+
 using namespace anna;
 using namespace anna::xml;
 
@@ -133,7 +138,7 @@ throw(RuntimeException) {
   const Namespace* ns;
 
   for(int i = 0; i < level; i ++)
-    result += ANNA_XML_COMPILER_TAB;
+    result += std::string(ANNA_XML_INDENTATION_SPACES, ' ');
 
   result += '<';
   writeFullName(node, result, flags);
@@ -150,6 +155,13 @@ throw(RuntimeException) {
     }
   }
 
+  // Sort node attributes (this is a compiler used for on-demand representation, this sorting is not permanent in the object which uses it):
+  if(flags & Mode::Sort) {
+    Node *nc_node = const_cast<Node*>(node);
+    std::sort(nc_node->attribute_begin(), nc_node->attribute_end(),
+              [](Attribute *a, Attribute *b) { return (std::strcmp(a->getName(), b->getName()) < 0); }); // sort alphabetically by attribute name
+  }
+
   for(Node::const_attribute_iterator ii = node->attribute_begin(), maxii = node->attribute_end(); ii != maxii; ii ++) {
     attribute = Node::attribute(ii);
     result += ' ';
@@ -203,7 +215,7 @@ throw(RuntimeException) {
 void Compiler::close(const Node* node, Result& result, const int level, const int flags)
 throw(RuntimeException) {
   for(int i = 0; i < level; i ++)
-    result += ANNA_XML_COMPILER_TAB;
+    result += std::string(ANNA_XML_INDENTATION_SPACES, ' ');
 
   result += "</";
   writeFullName(node, result, flags);