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