summaryrefslogtreecommitdiff
path: root/src/domhelpers.h
blob: fd386f8654f051e78b6ceb8cde2a13458023a2f6 (plain)
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
 * Copyright (c) 2004, Nate Nielsen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above
 *       copyright notice, this list of conditions and the
 *       following disclaimer.
 *     * Redistributions in binary form must reproduce the
 *       above copyright notice, this list of conditions and
 *       the following disclaimer in the documentation and/or
 *       other materials provided with the distribution.
 *     * The names of contributors to this software may not be
 *       used to endorse or promote products derived from this
 *       software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 *
 * CONTRIBUTORS
 *  Nate Nielsen <nielsen@memberwebs.com>
 *
 */

#ifndef __DOMHELPERS_H__
#define __DOMHELPERS_H__

#include "sablo.h"
#include <map>
#include <stack>
#include <set>

/*
 * DOMHelpers
 *
 * A collection of functions for doing some things with an XML DOM.
 * Used mainly by XMLComposer.
 */
class DOMHelpers
{
public:

    // Check if given node is an element with a certain name
    static bool isElement(const DOM::Node& node, const string& name);

    // Check if two elements have the same name and attributes
    static bool isEqualElement(const DOM::Element& el1, const DOM::Element& el2);

    // Copy attributes from one element to another optionaly ignoring some
    static void copyAttributes(const DOM::Element& src, DOM::Element& dest, const char** hideList);

    // Insert a child node after a given reference node
    static void insertAfter(DOM::Node& parent, const DOM::Node& node, const DOM::Node& ref);

    // Get containing element of a given name
    static DOM::Element getContainingElement(const DOM::Node& node, const string& name);

    // Get previous element (in XML flow) of a given name
    static DOM::Element getPriorElement(const DOM::Node& node, const string& name);

    // Get first child element of a given name
    static DOM::Element getChildElement(const DOM::Node& parent, const string& name);

    // Check if a given element is anothers ancestor
    static bool hasAncestor(const DOM::Node& ancestor, const DOM::Node& node);
};

/*
 * ElementTable
 *
 * A table of elements matched to their ids for quick access while applying
 * things like fonts, styles, lists from their definitions.
 */
class ElementTable :
    public std::map<wstring, DOM::Element>
{
public:
    void load(const DOM::Node& parent, const string& name);

    DOM::Element get(const wstring& id) const;

    bool has(const wstring& id) const
        { return find(id) != end(); }

    void removeIds();
};

// Some other handy types
typedef std::set<string> StringSet;
typedef std::stack<DOM::Node> NodeStack;

/*
 * ElementIterator
 *
 * For iterating through the elements in a document.
 */
class ElementIterator
    : public std::iterator<std::input_iterator_tag, DOM::Element, ptrdiff_t>
{
public:
    ElementIterator()
        { m_flags = AFTER_LAST; }
    ElementIterator(const DOM::Element& top)
        { m_top = top; m_flags = BEFORE_FIRST; next(); }
    ElementIterator(const ElementIterator& x)
        { m_top = x.m_top; m_current = x.m_current; m_flags = x.m_flags; }

    const DOM::Element& operator*() const
        { return m_current; }
    const DOM::Element* operator->() const
        { return (&**this); }
    const ElementIterator& operator++()
        { next(); return (*this); }
    const ElementIterator& operator--()
        { prev(); return (*this); }

    // Friend comparision functions
    friend bool operator==(const ElementIterator& x, const ElementIterator& y);
    friend bool operator!=(const ElementIterator& x, const ElementIterator& y);

// Implementation
protected:

    void next();
    DOM::Element nextel(DOM::Node node);

    void prev();
    DOM::Element prevel(DOM::Node node);

// Data
protected:

	enum
	{
		ITERATING,
		BEFORE_FIRST,
		AFTER_LAST
	};

    DOM::Element m_top;
    DOM::Element m_current;
	int m_flags;
};

// friend functions
inline bool operator==(const ElementIterator& x, const ElementIterator& y)
   { return y.m_current == x.m_current && y.m_flags == x.m_flags; }
inline bool operator!=(const ElementIterator& x, const ElementIterator& y)
   { return (!(x == y)); }

#endif // __DOMHELPERS_H__