bakery r108 - in trunk: . bakery/Document



Author: murrayc
Date: Wed Mar 26 16:42:54 2008
New Revision: 108
URL: http://svn.gnome.org/viewvc/bakery?rev=108&view=rev

Log:
2008-03-26  Murray Cumming  <murrayc murrayc com>

* bakery/Document/Document_XML.cc:
* bakery/Document/Document_XML.h:
Added add_indenting_white_space_to_node() for more useful indenting 
than libxml gives (because libxml gives up when it finds a text node).
Let's see how well this works.

Modified:
   trunk/ChangeLog
   trunk/bakery/Document/Document_XML.cc
   trunk/bakery/Document/Document_XML.h

Modified: trunk/bakery/Document/Document_XML.cc
==============================================================================
--- trunk/bakery/Document/Document_XML.cc	(original)
+++ trunk/bakery/Document/Document_XML.cc	Wed Mar 26 16:42:54 2008
@@ -239,4 +239,67 @@
 }
 
 
+void Document_XML::add_indenting_white_space_to_node(xmlpp::Node* node, const Glib::ustring& start_indent)
+{
+  if(!node)
+    node = get_node_document();
+
+  //Remove any previous indenting:
+  {
+  xmlpp::Node::NodeList list = node->get_children();
+  for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+  {
+    xmlpp::Node* child = *iter;
+    if(!child)
+      continue;
+
+    xmlpp::ContentNode* text = dynamic_cast<xmlpp::ContentNode*>(child);
+    if(text)
+    {
+      if(text->is_white_space())
+        node->remove_child(text);
+    }
+  }
+  }
+
+  //All indents have a newline, 
+  //and we add spaces each time we recurse:
+  Glib::ustring indent = start_indent;
+  if(indent.empty())
+    indent = "\n  ";
+  else
+    indent += "  ";
+
+  //Add indenting text items:
+  bool had_children = false;
+  xmlpp::Element* node_as_element = dynamic_cast<xmlpp::Element*>(node);
+  xmlpp::Node::NodeList list = node_as_element->get_children();
+  for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+  {
+    xmlpp::Node* child = *iter;
+    if(!child)
+      continue;
+
+    xmlpp::ContentNode* text = dynamic_cast<xmlpp::ContentNode*>(child);
+    if(text)
+    {
+      if(!text->is_white_space())
+        continue; //Don't change content items.
+    }
+
+    //Add a text item for the indenting, before the child:
+    //std::cout << "  Adding indent after node=" << child->get_name() << ": START" << indent << "END" << std::endl;
+    node_as_element->add_child_text_before(child, indent);
+    had_children = true;
+
+    //Recurse into the children:
+    add_indenting_white_space_to_node(child, indent);
+  }
+
+  //If it has children then add an indent before the closing tag:
+  if(had_children)
+    node_as_element->add_child_text(start_indent);
+}
+
+
 } //namespace Bakery.

Modified: trunk/bakery/Document/Document_XML.h
==============================================================================
--- trunk/bakery/Document/Document_XML.h	(original)
+++ trunk/bakery/Document/Document_XML.h	Wed Mar 26 16:42:54 2008
@@ -49,8 +49,16 @@
 
   /** Whether to add extra whitespace when writing the XML to disk.
    * Do not use this if whitespace is significant in your XML format.
+   * See also add_indenting_white_space().
    */
-  virtual void set_write_formatted(bool formatted = true);
+  void set_write_formatted(bool formatted = true);
+
+  /** Put each node on its own line and add white space for indenting,
+   * even if there are child text nodes.
+   * set_write_formatted() does not cause nodes to be indented if there are child text nodes,
+   * because it assumes that the white space is then significant.
+   */
+  void add_indenting_white_space();
   
   virtual bool set_xml(const Glib::ustring& strXML); //Parse the XML from the text.
   virtual Glib::ustring get_xml() const; //Get the text for the XML.
@@ -65,9 +73,10 @@
   virtual const xmlpp::Element* get_node_document() const; //e.g. <glom_document> (root name)
   virtual xmlpp::Element* get_node_document(); //e.g. <glom_document> (root name)
 
-
   virtual void Util_DOM_Write(Glib::ustring& refstrXML) const;
 
+  void add_indenting_white_space_to_node(xmlpp::Node* node = 0, const Glib::ustring& start_indent = Glib::ustring());
+
   typedef Bakery::Document type_base;
 
   //XML Parsing bits:



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]