File indexing completed on 2024-04-21 04:01:05

0001 /*
0002     This file is part of the syndication library
0003     SPDX-FileCopyrightText: 2006 Frank Osterfeld <osterfeld@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef SYNDICATION_ELEMENTWRAPPER_H
0009 #define SYNDICATION_ELEMENTWRAPPER_H
0010 
0011 #include <QSharedPointer>
0012 #include <QString>
0013 
0014 #include "syndication_export.h"
0015 
0016 class QDomElement;
0017 template<class T>
0018 class QList;
0019 
0020 namespace Syndication
0021 {
0022 /**
0023  * A wrapper for XML elements. This is the base class for the (lazy) wrappers
0024  * used in the RSS2 and Atom parsers. The wrapped element can be accessed
0025  * via element(). It also contains several helper functions for XML processing.
0026  *
0027  * @author Frank Osterfeld
0028  */
0029 class SYNDICATION_EXPORT ElementWrapper
0030 {
0031 public:
0032     /**
0033      * creates a element wrapper wrapping a null element.
0034      * isNull() will return @c true for these instances.
0035      */
0036     ElementWrapper();
0037 
0038     /**
0039      * Copy constructor.The instances share the same element.
0040      * @param other the element wrapper to copy
0041      */
0042     ElementWrapper(const ElementWrapper &other);
0043 
0044     /**
0045      * Creates an element wrapper wrapping the DOM element @c element
0046      * @param element the element to wrap
0047      */
0048     ElementWrapper(const QDomElement &element); // implicit
0049 
0050     /**
0051      * destructor
0052      */
0053     virtual ~ElementWrapper();
0054 
0055     /**
0056      * Assigns another element wrapper to this one. Both instances
0057      * share the same wrapped element instance.
0058      *
0059      * @param other the element wrapper to assign
0060      * @return reference to this instance
0061      */
0062     ElementWrapper &operator=(const ElementWrapper &other);
0063 
0064     /**
0065      * compares two wrappers. Two wrappers are equal if and only if
0066      * the wrapped elements are equal.
0067      * @param other another element wrapper to compare to
0068      */
0069     bool operator==(const ElementWrapper &other) const;
0070 
0071     /**
0072      * returns the wrapped resource.
0073      */
0074     const QDomElement &element() const;
0075 
0076     /**
0077      * returns whether the wrapped element is a null element
0078      * @return @c true if isNull() is true for the wrapped element,
0079      * @c false otherwise
0080      */
0081     Q_REQUIRED_RESULT bool isNull() const;
0082 
0083     /**
0084      * returns the xml:base value to be used for the wrapped element.
0085      * The xml:base attribute establishes the base URI for resolving any
0086      * relative references found in its scope (its own element and all
0087      * descendants). (See also completeURI())
0088      *
0089      * @return the xml:base value, or a null string if not set
0090      */
0091     Q_REQUIRED_RESULT QString xmlBase() const;
0092 
0093     /**
0094      * returns the xml:lang value to be used for the wrapped element.
0095      * The xml:lang attribute indicates the natural language for its element
0096      * and all descendants.
0097      *
0098      * @return the xml:lang value, or a null string if not set
0099      */
0100     Q_REQUIRED_RESULT QString xmlLang() const;
0101 
0102     /**
0103      * completes relative URIs with a prefix specified via xml:base.
0104      *
0105      * Example:
0106      * @code
0107      * xml:base="http://www.foo.org/", uri="announcements/bar.html"
0108      * @endcode
0109      *
0110      * is completed to @c http://www.foo.org/announcements/bar.html
0111      *
0112      * See also xmlBase().
0113      *
0114      * @param uri a possibly relative URI
0115      * @return the resolved, absolute URI (using xml:base), if @c uri is
0116      * a relative, valid URI. If @c uri is not valid, absolute, or no
0117      * xml:base is set in the scope of this element, @c uri is returned
0118      * unmodified.
0119      */
0120     Q_REQUIRED_RESULT QString completeURI(const QString &uri) const;
0121 
0122     /**
0123      * extracts the text from a child element, respecting namespaces. If
0124      * there is more than one child with the same tag name, the first one is
0125      * processed.
0126      * For instance, when the wrapped element is @c &lt;hisElement>:
0127      * @code
0128      * <thisElement>
0129      *     <atom:title>Hi there</atom:title>
0130      * </thisElement>
0131      * @endcode
0132      * @code
0133      * extractElementText("http://www.w3.org/2005/Atom", "title")
0134      * @endcode
0135      * will return the text content of @c atom:title, "Hi there".
0136      * (Assuming that "atom" is defined as "http://www.w3.org/2005/Atom")
0137      *
0138      * @param namespaceURI the namespace URI of the element to extract
0139      * @param localName the local name (local within its namespace) of the
0140      * element to extract
0141      * @return the (trimmed) text content of @c localName, or a null string
0142      * if there is no such tag
0143      */
0144 
0145     Q_REQUIRED_RESULT QString extractElementTextNS(const QString &namespaceURI, const QString &localName) const;
0146 
0147     /**
0148      * extracts the text from a child element, ignoring namespaces. For
0149      * instance, when the wrapped element is @c &lt;thisElement>:
0150      * @code
0151      * <thisElement>
0152      *     <title>Hi there</title>
0153      * </thisElement>
0154      * @endcode
0155      * @c extractElementText("title") will return the text content
0156      * of @c title, "Hi there".
0157      *
0158      * @param tagName the name of the element to extract
0159      * @return the (trimmed) text content of @c tagName, or a null string if
0160      * there is no such tag
0161      */
0162     Q_REQUIRED_RESULT QString extractElementText(const QString &tagName) const;
0163 
0164     /**
0165      * returns all child elements with tag name @c tagName
0166      * Contrary to QDomElement::elementsByTagName() only direct descendents
0167      * are returned.
0168      *
0169      * @param tagName the tag name of the elements to extract
0170      * @return a list of child elements with the given tag name
0171      */
0172     Q_REQUIRED_RESULT QList<QDomElement> elementsByTagName(const QString &tagName) const;
0173 
0174     /**
0175      * returns the child nodes of the wrapped element as XML.
0176      *
0177      * See childNodesAsXML(const QDomElement& parent) for details
0178      * @return XML serialization of the wrapped element's children
0179      */
0180     Q_REQUIRED_RESULT QString childNodesAsXML() const;
0181 
0182     /**
0183      * concatenates the XML representations of all children. Example: If
0184      * @c parent is an @c xhtml:body element like
0185      * @code
0186      * <xhtml:body><p>foo</p><blockquote>bar</blockquote></xhtml:body>
0187      * @endcode
0188      * this function returns
0189      * @code
0190      * <p>foo</p><blockquote>bar</blockquote>
0191      * @endcode
0192      *
0193      * namespace and xml:base information are preserved.
0194      *
0195      * @param parent the DOM element whose children should be returned as
0196      * XML
0197      * @return XML serialization of parent's children
0198      */
0199     Q_REQUIRED_RESULT static QString childNodesAsXML(const QDomElement &parent);
0200 
0201     /**
0202      * returns all child elements with tag name @c tagname
0203      * and namespace URI @c nsURI.
0204      * Contrary to QDomElement::elementsByTagNameNS() only direct
0205      * descendents are returned
0206      *
0207      * @param nsURI the namespace URI
0208      * @param tagName the local name (local within its namespace) of the
0209      * element to search for
0210      * @return a list of child elements with the given namespace URI
0211      * and tag name
0212      */
0213     Q_REQUIRED_RESULT QList<QDomElement> elementsByTagNameNS(const QString &nsURI, const QString &tagName) const;
0214 
0215     /**
0216      * searches the direct children of the wrapped element for an element
0217      * with a given namespace and tag name.
0218      *
0219      * @param nsURI the namespace URI
0220      * @param tagName the local name (local within its namespace) of the
0221      * element to search for
0222      * @return the first child element with the given namespace URI and tag
0223      * name, or a null element if no such element was found.
0224      */
0225     Q_REQUIRED_RESULT QDomElement firstElementByTagNameNS(const QString &nsURI, const QString &tagName) const;
0226 
0227     /**
0228      * Returns the wrapped element's text or an empty string.
0229      * For more information, see QDomElement::text();
0230      */
0231     Q_REQUIRED_RESULT QString text() const;
0232 
0233     /**
0234      * Returns the attribute called name. If the attribute does not exist
0235      * defValue is returned.
0236      * (which is a null string by default).
0237      *
0238      * @param name tag name
0239      * @param defValue the default value
0240      */
0241     Q_REQUIRED_RESULT QString attribute(const QString &name, const QString &defValue = QString()) const;
0242 
0243     /**
0244      * Returns the attribute with the local @c name localName and the
0245      * namespace URI @c nsURI.
0246      * If the attribute does not exist @c defValue is returned (which is a
0247      * null string by default).
0248      *
0249      * @param nsURI namespace URI
0250      * @param localName local tag name
0251      * @param defValue the default value
0252      */
0253     Q_REQUIRED_RESULT QString attributeNS(const QString &nsURI, const QString &localName, const QString &defValue = QString()) const;
0254 
0255     /**
0256      * Returns true if this element has an attribute called @c name;
0257      * otherwise returns @c false.
0258      *
0259      * @param name the attribute name (without namespace)
0260      */
0261     Q_REQUIRED_RESULT bool hasAttribute(const QString &name) const;
0262 
0263     /**
0264      * Returns true if this element has an attribute with the local name
0265      * localName and the namespace URI nsURI; otherwise returns false.
0266      *
0267      * @param nsURI namespace URI
0268      * @param localName local attribute name
0269      */
0270     Q_REQUIRED_RESULT bool hasAttributeNS(const QString &nsURI, const QString &localName) const;
0271 
0272 private:
0273     class ElementWrapperPrivate;
0274     QSharedPointer<ElementWrapperPrivate> d;
0275 };
0276 
0277 } // namespace Syndication
0278 
0279 #endif // SYNDICATION_ELEMENTWRAPPER_H