Remove redundant, unnamed root XML node from parsed documents

XML_Node::build will make that node the root node (i.e. the 'ctml' node)
of the tree, instead of giving that node a child node containing the actual
root node.
This commit is contained in:
Ray Speth 2015-04-20 14:18:01 -04:00
parent 39b93d3690
commit b0e5b13913
5 changed files with 52 additions and 25 deletions

View file

@ -598,10 +598,7 @@ public:
/*!
* This is a wrapper around the static routine write_int(). All this does
* is add an endl on to the output stream. write_int() is fine, but the
* last endl wasn't being written. It also checks for the special name
* "`--`". If found and we are at the root of the xml tree, then the block
* is skipped and the children are processed. "`--`" is used to denote the
* top of the tree.
* last endl wasn't being written.
*
* @param s ostream to write to
* @param level Indentation level to work from

View file

@ -757,6 +757,7 @@ void XML_Node::build(std::istream& f)
string nm, nm2, val;
XML_Node* node = this;
map<string, string> node_attribs;
bool first = true;
while (!f.eof()) {
node_attribs.clear();
nm = r.readTag(node_attribs);
@ -770,14 +771,24 @@ void XML_Node::build(std::istream& f)
int lnum = r.m_line;
if (nm[nm.size() - 1] == '/') {
nm2 = nm.substr(0,nm.size()-1);
node = &node->addChild(nm2);
if (first) {
node->setName(nm2);
first = false;
} else {
node = &node->addChild(nm2);
}
node->addValue("");
node->attribs() = node_attribs;
node->setLineNumber(lnum);
node = node->parent();
} else if (nm[0] != '/') {
if (nm[0] != '!' && nm[0] != '-' && nm[0] != '?') {
node = &node->addChild(nm);
if (first) {
node->setName(nm);
first = false;
} else {
node = &node->addChild(nm);
}
val = r.readValue();
node->addValue(val);
node->attribs() = node_attribs;
@ -1067,15 +1078,8 @@ void XML_Node::write_int(std::ostream& s, int level, int numRecursivesAllowed) c
void XML_Node::write(std::ostream& s, const int level, int numRecursivesAllowed) const
{
if (m_name == "--" && m_root == this) {
for (size_t i = 0; i < m_children.size(); i++) {
m_children[i]->write_int(s,level, numRecursivesAllowed-1);
s << endl;
}
} else {
write_int(s, level, numRecursivesAllowed);
s << endl;
}
write_int(s, level, numRecursivesAllowed);
s << endl;
}
XML_Node& XML_Node::root() const

View file

@ -529,14 +529,12 @@ void Elements::addElementsFromXML(const XML_Node& phase)
}
XML_Node* doc = get_XML_File(element_database);
XML_Node* dbe = &doc->child("ctml/elementData");
XML_Node* dbe = &doc->child("elementData");
XML_Node& root = phase.root();
XML_Node* local_db = 0;
if (root.hasChild("ctml")) {
if (root.child("ctml").hasChild("elementData")) {
local_db = &root.child("ctml/elementData");
}
if (root.hasChild("elementData")) {
local_db = &root.child("elementData");
}
int nel = static_cast<int>(enames.size());

View file

@ -513,14 +513,12 @@ void installElements(Phase& th, const XML_Node& phaseNode)
}
XML_Node* doc = get_XML_File(element_database);
XML_Node* dbe = &doc->child("ctml/elementData");
XML_Node* dbe = &doc->child("elementData");
XML_Node& root = phaseNode.root();
XML_Node* local_db = 0;
if (root.hasChild("ctml")) {
if (root.child("ctml").hasChild("elementData")) {
local_db = &root.child("ctml/elementData");
}
if (root.hasChild("elementData")) {
local_db = &root.child("elementData");
}
for (size_t i = 0; i < enames.size(); i++) {

30
test/general/test_xml.cpp Normal file
View file

@ -0,0 +1,30 @@
#include "gtest/gtest.h"
#include "cantera/base/xml.h"
#include <fstream>
namespace Cantera
{
TEST(XML_Node, read_write)
{
// Check that we can re-read our own XML output
XML_Node node1, node2;
std::stringstream out;
std::ifstream xmlfile("../data/air-no-reactions.xml");
node1.build(xmlfile);
node1.write(out);
node2.build(out);
ASSERT_EQ(node2.name(), "ctml");
ASSERT_TRUE(node2.hasChild("speciesData"));
std::vector<XML_Node*> species1, species2;
species1 = node1.child("speciesData").getChildren("species");
species2 = node2.child("speciesData").getChildren("species");
ASSERT_EQ(species1.size(), species2.size());
for (size_t i = 0; i < species1.size(); i++) {
ASSERT_EQ(species1[i]->attrib("name"), species2[i]->attrib("name"));
}
}
}