From b0e5b139130064853ae82ba70ea8205b478dcd72 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Mon, 20 Apr 2015 14:18:01 -0400 Subject: [PATCH] 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. --- include/cantera/base/xml.h | 5 +---- src/base/xml.cpp | 26 +++++++++++++++----------- src/thermo/Elements.cpp | 8 +++----- src/thermo/ThermoFactory.cpp | 8 +++----- test/general/test_xml.cpp | 30 ++++++++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 test/general/test_xml.cpp diff --git a/include/cantera/base/xml.h b/include/cantera/base/xml.h index 202ae1c62..1361ac6fa 100644 --- a/include/cantera/base/xml.h +++ b/include/cantera/base/xml.h @@ -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 diff --git a/src/base/xml.cpp b/src/base/xml.cpp index 5cc3515e2..08ec8be95 100644 --- a/src/base/xml.cpp +++ b/src/base/xml.cpp @@ -757,6 +757,7 @@ void XML_Node::build(std::istream& f) string nm, nm2, val; XML_Node* node = this; map 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 diff --git a/src/thermo/Elements.cpp b/src/thermo/Elements.cpp index b099e5ee9..a1800b5c5 100644 --- a/src/thermo/Elements.cpp +++ b/src/thermo/Elements.cpp @@ -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(enames.size()); diff --git a/src/thermo/ThermoFactory.cpp b/src/thermo/ThermoFactory.cpp index cb6fe1206..3dd3266c9 100644 --- a/src/thermo/ThermoFactory.cpp +++ b/src/thermo/ThermoFactory.cpp @@ -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++) { diff --git a/test/general/test_xml.cpp b/test/general/test_xml.cpp new file mode 100644 index 000000000..06abf2194 --- /dev/null +++ b/test/general/test_xml.cpp @@ -0,0 +1,30 @@ +#include "gtest/gtest.h" +#include "cantera/base/xml.h" +#include + +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 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")); + } +} + +}