1/*
2 * This file is part of the syndication library
3 *
4 * Copyright (C) 2006 Frank Osterfeld <osterfeld@kde.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22#ifndef SYNDICATION_ELEMENTWRAPPER_H
23#define SYNDICATION_ELEMENTWRAPPER_H
24
25#include <QtCore/QString>
26
27#include <boost/shared_ptr.hpp>
28
29#include "ksyndication_export.h"
30
31class QDomElement;
32template <class T> class QList;
33
34namespace Syndication {
35
36/**
37 * A wrapper for XML elements. This is the base class for the (lazy) wrappers
38 * used in the RSS2 and Atom parsers. The wrapped element can be accessed
39 * via element(). It also contains several helper functions for XML processing.
40 *
41 * @author Frank Osterfeld
42 */
43class SYNDICATION_EXPORT ElementWrapper
44{
45 public:
46
47 /**
48 * creates a element wrapper wrapping a null element.
49 * isNull() will return @c true for these instances.
50 */
51 ElementWrapper();
52
53 /**
54 * Copy constructor.The instances share the same element.
55 * @param other the element wrapper to copy
56 */
57 ElementWrapper(const ElementWrapper& other);
58
59 /**
60 * Creates an element wrapper wrapping the DOM element @c element
61 * @param element the element to wrap
62 */
63 ElementWrapper(const QDomElement& element); // implicit
64
65 /**
66 * destructor
67 */
68 virtual ~ElementWrapper();
69
70 /**
71 * Assigns another element wrapper to this one. Both instances
72 * share the same wrapped element instance.
73 *
74 * @param other the element wrapper to assign
75 * @return reference to this instance
76 */
77 ElementWrapper& operator=(const ElementWrapper& other);
78
79 /**
80 * compares two wrappers. Two wrappers are equal if and only if
81 * the wrapped elements are equal.
82 * @param other another element wrapper to compare to
83 */
84 bool operator==(const ElementWrapper& other) const;
85
86 /**
87 * returns the wrapped resource.
88 */
89 const QDomElement& element() const;
90
91 /**
92 * returns whether the wrapped element is a null element
93 * @return @c true if isNull() is true for the wrapped element,
94 * @c false otherwise
95 */
96 bool isNull() const;
97
98 /**
99 * returns the xml:base value to be used for the wrapped element.
100 * The xml:base attribute establishes the base URI for resolving any
101 * relative references found in its scope (its own element and all
102 * descendants). (See also completeURI())
103 *
104 * @return the xml:base value, or a null string if not set
105 */
106 QString xmlBase() const;
107
108 /**
109 * returns the xml:lang value to be used for the wrapped element.
110 * The xml:lang attribute indicates the natural language for its element
111 * and all descendants.
112 *
113 * @return the xml:lang value, or a null string if not set
114 */
115 QString xmlLang() const;
116
117 /**
118 * completes relative URIs with a prefix specified via xml:base.
119 *
120 * Example:
121 * @code
122 * xml:base="http://www.foo.org/", uri="announcements/bar.html"
123 * @endcode
124 *
125 * is completed to @c http://www.foo.org/announcements/bar.html
126 *
127 * See also xmlBase().
128 *
129 * @param uri a possibly relative URI
130 * @return the resolved, absolute URI (using xml:base), if @c uri is
131 * a relative, valid URI. If @c uri is not valid, absolute, or no
132 * xml:base is set in the scope of this element, @c uri is returned
133 * unmodified.
134 */
135 QString completeURI(const QString& uri) const;
136
137 /**
138 * extracts the text from a child element, respecting namespaces. If
139 * there is more than one child with the same tag name, the first one is
140 * processed.
141 * For instance, when the wrapped element is @c &lt;hisElement>:
142 * @code
143 * <thisElement>
144 * <atom:title>Hi there</atom:title>
145 * </thisElement>
146 * @endcode
147 * @code
148 * extractElementText("http://www.w3.org/2005/Atom", "title")
149 * @endcode
150 * will return the text content of @c atom:title, "Hi there".
151 * (Assuming that "atom" is defined as "http://www.w3.org/2005/Atom")
152 *
153 * @param namespaceURI the namespace URI of the element to extract
154 * @param localName the local name (local within its namespace) of the
155 * element to extract
156 * @return the (trimmed) text content of @c localName, or a null string
157 * if there is no such tag
158 */
159
160 QString extractElementTextNS(const QString& namespaceURI,
161 const QString& localName) const;
162
163 /**
164 * extracts the text from a child element, ignoring namespaces. For
165 * instance, when the wrapped element is @c &lt;thisElement>:
166 * @code
167 * <thisElement>
168 * <title>Hi there</title>
169 * </thisElement>
170 * @endcode
171 * @c extractElementText("title") will return the text content
172 * of @c title, "Hi there".
173 *
174 * @param tagName the name of the element to extract
175 * @return the (trimmed) text content of @c tagName, or a null string if
176 * there is no such tag
177 */
178 QString extractElementText(const QString& tagName) const;
179
180 /**
181 * returns all child elements with tag name @c tagName
182 * Contrary to QDomElement::elementsByTagName() only direct descendents
183 * are returned.
184 *
185 * @param tagName the tag name of the elements to extract
186 * @return a list of child elements with the given tag name
187 */
188 QList<QDomElement> elementsByTagName(const QString& tagName) const;
189
190 /**
191 * returns the child nodes of the wrapped element as XML.
192 *
193 * See childNodesAsXML(const QDomElement& parent) for details
194 * @return XML serialization of the wrapped element's children
195 */
196 QString childNodesAsXML() const;
197
198 /**
199 * concatenates the XML representations of all children. Example: If
200 * @c parent is an @c xhtml:body element like
201 * @code
202 * <xhtml:body><p>foo</p><blockquote>bar</blockquote></xhtml:body>
203 * @endcode
204 * this function returns
205 * @code
206 * <p>foo</p><blockquote>bar</blockquote>
207 * @endcode
208 *
209 * namespace and xml:base information are preserved.
210 *
211 * @param parent the DOM element whose children should be returned as
212 * XML
213 * @return XML serialization of parent's children
214 */
215 static QString childNodesAsXML(const QDomElement& parent);
216
217 /**
218 * returns all child elements with tag name @c tagname
219 * and namespace URI @c nsURI.
220 * Contrary to QDomElement::elementsByTagNameNS() only direct
221 * descendents are returned
222 *
223 * @param nsURI the namespace URI
224 * @param tagName the local name (local within its namespace) of the
225 * element to search for
226 * @return a list of child elements with the given namespace URI
227 * and tag name
228 */
229 QList<QDomElement> elementsByTagNameNS(const QString& nsURI,
230 const QString& tagName) const;
231
232 /**
233 * searches the direct children of the wrapped element for an element
234 * with a given namespace and tag name.
235 *
236 * @param nsURI the namespace URI
237 * @param tagName the local name (local within its namespace) of the
238 * element to search for
239 * @return the first child element with the given namespace URI and tag
240 * name, or a null element if no such element was found.
241 */
242 QDomElement firstElementByTagNameNS(const QString& nsURI,
243 const QString& tagName) const;
244
245 /**
246 * Returns the wrapped element's text or an empty string.
247 * For more information, see QDomElement::text();
248 */
249 QString text() const;
250
251 /**
252 * Returns the attribute called name. If the attribute does not exist
253 * defValue is returned.
254 * (which is a null string by default).
255 *
256 * @param name tag name
257 * @param defValue the default value
258 */
259 QString attribute(const QString& name,
260 const QString& defValue=QString()) const;
261
262 /**
263 * Returns the attribute with the local @c name localName and the
264 * namespace URI @c nsURI.
265 * If the attribute does not exist @c defValue is returned (which is a
266 * null string by default).
267 *
268 * @param nsURI namespace URI
269 * @param localName local tag name
270 * @param defValue the default value
271 */
272 QString attributeNS(const QString& nsURI, const QString& localName,
273 const QString& defValue=QString()) const;
274
275
276 /**
277 * Returns true if this element has an attribute called @c name;
278 * otherwise returns @c false.
279 *
280 * @param name the attribute name (without namespace)
281 */
282 bool hasAttribute(const QString& name) const;
283
284 /**
285 * Returns true if this element has an attribute with the local name
286 * localName and the namespace URI nsURI; otherwise returns false.
287 *
288 * @param nsURI namespace URI
289 * @param localName local attribute name
290 */
291 bool hasAttributeNS(const QString& nsURI, const QString& localName) const;
292
293 private:
294
295 class ElementWrapperPrivate;
296 boost::shared_ptr<ElementWrapperPrivate> d;
297};
298
299} // namespace Syndication
300
301#endif // SYNDICATION_ELEMENTWRAPPER_H
302