bool Parser::proceedNode(Node* node, rapidxml::xml_node<>* xml_node) { if (node && xml_node) { // Check required attributes for (std::map<std::string, bool>::const_iterator it = node->getAttributes().begin(); it != node->getAttributes().end(); ++it) { XMLAttribute* attr = xml_node->first_attribute(it->first.c_str()); if (attr == NULL && it->second) { std::cout << "Error: Attribute `" << it->first << "` in node `" << node->getName() << "` is required." << std::endl; return false; } } // Check unsupported attributes for (XMLAttribute* attr = xml_node->first_attribute(); attr; attr = attr->next_attribute()) { if (!node->hasAttribute(attr->name())) std::cout << "Warning: Attribute `" << attr->name() << "` in node `" << node->getName() << "` not supported." << std::endl; } // Node callback if (node->getName().compare(xml_node->name()) == 0) (*node)(xml_node); // Proceed sibling nodes XMLNode* sibling = xml_node->next_sibling(); if (sibling && sibling->name()) { if (node->hasSibling(sibling->name())) { if (!this->proceedNode(node->getSibling(sibling->name()), sibling)) return false; } else std::cout << "Warning: Sibling `" << sibling->name() << "` of `" << node->getName() << "` not supported." << std::endl; } // Proceed child nodes XMLNode* child = xml_node->first_node(); if (child && child->name()) { if (node->hasChild(child->name())) { if (!this->proceedNode(node->getChild(child->name()), child)) return false; } else std::cout << "Warning: Child `" << child->name() << "` of `" << node->getName() << "` not supported." << std::endl; } } return true; }
std::string getXMLTypeAttribute(const XMLNode& node) { if (rapidxml::count_attributes(const_cast<XMLNode*>(&node)) != 1) raiseXMLException(node, "Expected 1 attribute"); XMLAttribute* attr = node.first_attribute(); if (strcmp(attr->name(), "type")) raiseXMLException(node, "Missing \"type\" attribute"); return std::string(attr->value()); }
Shape* Shape::buildFromXMLNode(XMLNode& node) { if (rapidxml::count_attributes(&node) != 1) raiseXMLException(node, "Expected 1 attribute"); XMLAttribute* attr = node.first_attribute(); if (strcmp(attr->name(), "type")) raiseXMLException(node, "Missing \"type\" attribute"); const std::string type(attr->value()); if (type == "Planet") return Planet::buildFromXMLNode(node); else if (type == "Star") return Star::buildFromXMLNode(node); raiseXMLException(node, std::string("Invalid type: ") + type); return nullptr; // Keep compiler happy }