Re: [libxml++] write_to_file_formatted problem



On Tue, 2008-03-25 at 23:09 -0300, Ignacio Espinosa wrote:
> El mar, 18-03-2008 a las 11:54 -0300, Ignacio Espinosa escribió:
> > El mar, 18-03-2008 a las 12:59 +0100, Murray Cumming escribió:
> > > 
> > > That shouldn't be necessary. Could you add a simple-as-possible test
> > > case to bugzilla?
> > > 
> > Done: http://bugzilla.gnome.org/show_bug.cgi?id=523187
> > 
> > Thanks for the answer :)
> > 
> If the original document it's as simple as decribed in bugtrack, this
> procedure (based on dom_parser example) will fix the problem (not
> bug :P):
> 
> void clean_document (xmlpp::Node* node)
> {
> 	xmlpp::ContentNode* nodeContent =
> dynamic_cast<xmlpp::ContentNode*>(node);
> 	xmlpp::TextNode* nodeText = dynamic_cast<xmlpp::TextNode*>(node);
> 
> 	if(nodeText && nodeText->is_white_space())
> 	{
> 		xmlpp::Element *parent_e = node->get_parent();
> 		xmlpp::Node *parent_n = dynamic_cast<xmlpp::Node*>(parent_e);
> 		parent_n->remove_child(node);
> 		return;
> 	}
> 
> 	if(!nodeContent)
> 	{
> 		xmlpp::Node::NodeList list = node->get_children();
> 		for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter !=
> list.end(); ++iter)
> 			clean_document(*iter);
> 	}
> }

That seems to just remove formatting.

I created this little highly-inefficient
add_indenting_white_space_to_node() function in Bakery to correct or
add indentation. It works for Glom, at least:
http://svn.gnome.org/viewvc/bakery/trunk/bakery/Document/Document_XML.cc?revision=108&view=markup

Here is the current code for that function from svn:

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);
}

-- 
murrayc murrayc com
www.murrayc.com
www.openismus.com





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