-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtext_selector.hpp
139 lines (115 loc) · 4.08 KB
/
text_selector.hpp
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
// Copyright Morten Bendiksen 2014 - 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MEDIASEQUENCER_PLUGIN_UTIL_XPATH_TEXT_SELECTOR_HPP
#define MEDIASEQUENCER_PLUGIN_UTIL_XPATH_TEXT_SELECTOR_HPP
#include <numeric>
namespace mediasequencer { namespace plugin { namespace util { namespace xpath {
// Predicate for filtering out nodes that does not contain
// the given name.
template <typename Context>
struct node_contains_text {
typedef bool result_type;
bool operator()(Context const& c) const {
return c.text().find(text) != std::string::npos;
}
std::string text;
node_contains_text(std::string text) :text(text) {}
};
// the type for the text selector
struct _text {
};
/// The selector for filtering out nodes that does not cointain
/// the give text. 'range | text_contains("foo")' will give
/// all nodes from the range which has as text content a string
/// that contains the substring "foo"
struct text_contains {
std::string text;
text_contains(std::string text) : text(text)
{}
};
// the type for the first_text selector
struct _first_text {
};
// the type for the xml_string selector
struct _xml_string {
};
namespace {
/// The text selector. Gives the text content of the nodes in the input as
/// a range of strings, e.g. 'range | text'
const _text text;
/// The first_text selector. Gives the text content of the first node in the input as
/// a string, e.g. 'range | first_text'
const _first_text first_text;
/// The xml_string selector. Gives the xml representation of a node as a string. I.e.
/// ' range | first | xml_string' gives one string representing the first node in the
/// range.
const _xml_string xml_string;
}
// Used to transform a context node to a string containing
// the nodes contained text.
template <typename Context>
struct node_to_text {
typedef std::string result_type;
std::string operator()(Context const& c) const {
return c.text();
}
};
/// The concatenate selector will concatenate the strings in the
/// input range to one string. It takes a string as parameter which
/// will be intertwined between each input string in the output
/// string. I.e. given a range with nodes named 'a', 'b' and 'c',
/// 'range | name | concatenate("-")' would give the string "a-b-c"
struct concatenate {
concatenate(std::string delimiter) : delimiter(delimiter) {}
std::string delimiter;
};
// Implements the pipe operator for the text selector
template<typename Range>
boost::range_detail::transformed_range
<node_to_text<typename Range::iterator::value_type>,
const Range>
operator|(Range const& range, _text)
{
return range | boost::adaptors::transformed(node_to_text<typename Range::iterator::value_type>());
}
// Implements the pipe operator for the first_text selector
template<typename Range>
std::string
operator|(Range const& range, _first_text) {
auto r = range | text;
if (r.begin() != r.end()) {
return *(r.begin());
} else {
return "";
}
}
// Implements the pipe operator for the text_contains selector
template<typename Range>
boost::range_detail::filtered_range
<node_contains_text<typename Range::iterator::value_type>,
const Range>
operator|(Range const& range, text_contains p)
{
return range | boost::adaptors::filtered(
node_contains_text<typename Range::iterator::value_type>(p.text));
}
// Implements the pipe operator for the concatenate selector
template<typename Range>
std::string
operator|(Range const& range, concatenate c) {
return
std::accumulate(
range.begin(), range.end(), std::string(""),
[c](std::string& v, std::string const& x)
{ return v +(v.size()==0?"":c.delimiter)+x; } );
}
// Implements the pipe operator for the xml_string selector
template <typename Context>
std::string
operator|(Context const& c, _xml_string) {
return c.to_text();
}
}}}}
#endif // MEDIASEQUENCER_PLUGIN_UTIL_XPATH_TEXT_SELECTOR_HPP