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