Kitlist
A list manager for maintaining kit lists
Loading...
Searching...
No Matches
kitparser.cpp
Go to the documentation of this file.
1/*
2
3 This file is part of Kitlist, a program to maintain a simple list
4 of items and assign items to one or more categories.
5
6 Copyright (C) 2008-2025 Frank Dean
7
8 Kitlist is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Kitlist is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Kitlist. If not, see <http://www.gnu.org/licenses/>.
20
21*/
22#include "kitparser.hpp"
23#include "pugixml.hpp"
24#include <iostream>
25#include <memory>
26
27using namespace pugi;
28using namespace std;
29
30void KitParser::parse_items(const xml_node& node)
31{
32 for (xml_node n : node.children()) {
33 string node_name = n.name();
34 if (node_name == "item") {
35 shared_ptr<Item> i{new Item()};
36 i->id = n.attribute("id").as_llong();
37 i->checked = n.attribute("checked").as_bool();
38 i->name = n.child_value();
39 model->add_item(i);
40 } else {
41 cerr << "Unknown node named \"" << node_name << "\"\n";
42 }
43 }
44}
45
46void KitParser::parse_categories(const xml_node& node)
47{
48 for (xml_node n : node.children()) {
49 string node_name = n.name();
50 if (node_name == "category") {
51 shared_ptr<Category> c{new Category()};
52 c->id = n.attribute("id").as_llong();
53 c->name = n.child_value("category-name");
54 model->add_category(c);
55 // std::cout << "Category " << c->id << " " << c->name << '\n';
56 auto cat_items = n.child("category-items");
57 if (cat_items.type() == node_null) {
58 cerr << "No category-items\n";
59 }
60 for (xml_node category_item : cat_items.children()) {
61 string ci_name = category_item.name();
62 if (ci_name == "category-item") {
63 auto id = category_item.attribute("id").as_llong();
64 model->associate_item_with_category(id, c);
65 } else {
66 cerr << "Unexpected node named \"" << ci_name << "\"\n";
67 }
68 }
69 } else {
70 cerr << "Unknown node named \"" << node_name << "\"\n";
71 }
72 }
73}
74
75unique_ptr<Model> KitParser::parse()
76{
77 xml_document doc;
78 xml_parse_result result = doc.load_file(filename.c_str());
79 if (result) {
80 xml_node gpx = doc.child("kitlist");
81 for (xml_node n : gpx.children()) {
82 string node_name = n.name();
83 if (node_name == "items") {
84 parse_items(n);
85 } else if (node_name == "categories") {
87 } else {
88 cerr << "Unknown node named \"" << node_name << "\"\n";
89 }
90 }
91 } else {
92 throw parse_exception("Failure parsing kitlist XML data");
93 }
94 model->set_dirty(false);
95 return std::move(model);
96}
Represents a Category having a many-to-many relationship to zero or more Item instances.
Definition category.hpp:41
Represents a Item having a many-to-many relationship to zero or more Category instances.
Definition item.hpp:41
XML parsing error.
Definition kitparser.hpp:86
void parse_categories(const pugi::xml_node &node)
Parses the categories XML node.
Definition kitparser.cpp:46
std::unique_ptr< Model > model
The Model representing the parsed file.
Definition kitparser.hpp:49
void parse_items(const pugi::xml_node &node)
Parses the items XML node.
Definition kitparser.cpp:30
std::unique_ptr< Model > parse()
Parses the XML, building the data Model.
Definition kitparser.cpp:75
std::string filename
The filename to be parsed.
Definition kitparser.hpp:46
Copyright 2008-2025 Frank Dean