1 /***************************************************************************
2 nodeparser.cpp
3 -------------------
4 copyright : (C) 2005 by Ace Jones
5 email : acejones@users.sourceforge.net
6 ***************************************************************************/
7 /**@file
8 * \brief Implementation of nodeparser object, which facilitiates searching
9 * for nodes in an XML file using a notation similiar to XPath.
10 */
11 /***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20 #include "nodeparser.h"
21
22 using std::string;
23 using std::vector;
24
NodeParser(const xmlpp::Node::NodeList & list)25 NodeParser::NodeParser(const xmlpp::Node::NodeList& list): xmlpp::Node::NodeList(list)
26 {
27 }
28
NodeParser(const xmlpp::Node * node)29 NodeParser::NodeParser(const xmlpp::Node* node)
30 {
31 push_back(const_cast<xmlpp::Node*>(node));
32 }
33
NodeParser(const xmlpp::DomParser & parser)34 NodeParser::NodeParser(const xmlpp::DomParser& parser)
35 {
36 xmlpp::Node* node = parser.get_document()->get_root_node();
37 push_back(const_cast<xmlpp::Node*>(node));
38 }
39
Path(const xmlpp::Node * node,const std::string & path)40 NodeParser NodeParser::Path(const xmlpp::Node* node, const std::string& path)
41 {
42 //std::cout << __PRETTY_FUNCTION__ << std::endl;
43
44 NodeParser result;
45
46 // split path string into the 1st level, and the rest
47 std::string key = path;
48 std::string remainder;
49 std::string::size_type token_pos = path.find('/');
50 if ( token_pos != std::string::npos )
51 {
52 key = path.substr(0, token_pos );
53 remainder = path.substr( token_pos + 1 );
54 }
55
56 // find the first level nodes that match
57 xmlpp::Node::NodeList list = node->get_children();
58 for (xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
59 {
60 if ( (*iter)->get_name() == key )
61 {
62 // if there is still some path left, ask for the rest of the path from those nodes.
63 if ( remainder.length() )
64 {
65 NodeParser remain_list = NodeParser(*iter).Path(remainder);
66 result.splice(result.end(), remain_list);
67 }
68
69 // otherwise add the node to the result list.
70 else
71 result.push_back(*iter);
72 }
73 }
74
75 return result;
76 }
77
Path(const std::string & path) const78 NodeParser NodeParser::Path(const std::string& path) const
79 {
80 //std::cout << __PRETTY_FUNCTION__ << std::endl;
81 NodeParser result;
82
83 for (const_iterator iter = begin(); iter != end(); ++iter)
84 {
85 NodeParser iter_list = Path(*iter, path);
86 result.splice(result.end(), iter_list);
87 }
88
89 return result;
90 }
91
Select(const std::string & key,const std::string & value) const92 NodeParser NodeParser::Select(const std::string& key, const std::string& value) const
93 {
94 //std::cout << __PRETTY_FUNCTION__ << std::endl;
95 NodeParser result;
96 for (const_iterator iter = begin(); iter != end(); ++iter)
97 {
98 xmlpp::Node::NodeList list = (*iter)->get_children();
99 for (xmlpp::Node::NodeList::const_iterator iter3 = list.begin(); iter3 != list.end(); ++iter3)
100 {
101 if ( (*iter3)->get_name() == key )
102 {
103 xmlpp::Node::NodeList list = (*iter3)->get_children();
104 for (xmlpp::Node::NodeList::const_iterator iter4 = list.begin(); iter4 != list.end(); ++iter4)
105 {
106 const xmlpp::TextNode* nodeText = dynamic_cast<const xmlpp::TextNode*>(*iter4);
107 if ( nodeText && nodeText->get_content() == value )
108 result.push_back(*iter);
109 break;
110 }
111 }
112 }
113 }
114 return result;
115 }
116
Text(void) const117 vector<string> NodeParser::Text(void) const
118 {
119 vector<string> result;
120
121 // Go through the list of nodes
122 for (xmlpp::Node::NodeList::const_iterator iter = begin(); iter != end(); ++iter)
123 {
124 // Find the text child node, and print that
125 xmlpp::Node::NodeList list = (*iter)->get_children();
126 for (xmlpp::Node::NodeList::const_iterator iter2 = list.begin(); iter2 != list.end(); ++iter2)
127 {
128 const xmlpp::TextNode* nodeText = dynamic_cast<const xmlpp::TextNode*>(*iter2);
129 if ( nodeText )
130 {
131 result.push_back(nodeText->get_content());
132 }
133 }
134 }
135 if ( result.empty() )
136 result.push_back(string());
137 return result;
138 }
139
140 // vim:cin:si:ai:et:ts=2:sw=2:
141