Imported Upstream version 2.91.2
[platform/upstream/libxml++.git] / libxml++ / nodes / element.h
1 /* element.h
2  * libxml++ and this file are copyright (C) 2000 by Ari Johnson, and
3  * are covered by the GNU Lesser General Public License, which should be
4  * included with libxml++ as the file COPYING.
5  */
6
7 #ifndef __LIBXMLPP_NODES_ELEMENT_H
8 #define __LIBXMLPP_NODES_ELEMENT_H
9
10 #include <libxml++/nodes/node.h>
11 #include <libxml++/attribute.h>
12 #include <libxml++/nodes/commentnode.h>
13 #include <libxml++/nodes/cdatanode.h>
14 #include <libxml++/nodes/textnode.h>
15 #include <libxml++/nodes/processinginstructionnode.h>
16 #include <libxml++/nodes/entityreference.h>
17
18 namespace xmlpp
19 {
20
21 /** Element nodes have attributes as well as child nodes. This will be instantiated by the parser.
22  */
23 class Element : public Node
24 {
25 public:
26   explicit Element(_xmlNode* node);
27   ~Element() override;
28
29   typedef std::list<Attribute*> AttributeList;
30   typedef std::list<const Attribute*> const_AttributeList;
31
32   /** Add a namespace declaration to this node which will apply to this node and all children.
33    *
34    * If the added namespace prefix is equal to the prefix associated to the node,
35    * the associated namespace of the node itself is updated, but child nodes are
36    * not updated. If you use this method on a node after children have been added,
37    * it may be necessary to save the XML document and reparse it to get correct
38    * namespaces on all nodes.
39    *
40    * @param ns_uri The namespace to associate with the prefix,
41    *               or to use as the default namespace if no prefix is specified.
42    * @param ns_prefix The namespace prefix. If no prefix is specified then the
43    *                  namespace URI will be the default namespace.
44    * @throws xmlpp::exception If a new namespace node cannot be created,
45    *         e.g. because a namespace with the same prefix but another URI already exists.
46    */
47   void set_namespace_declaration(const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix = Glib::ustring());
48
49   /** Obtain the list of explicitly set attributes for this element.
50    * @returns The list of explicitly set attributes.
51    */
52   AttributeList get_attributes();
53
54   /** Obtain the list of explicitly set attributes for this element.
55    * @returns The list of explicitly set attributes.
56    */
57   const_AttributeList get_attributes() const;
58
59   /** Get the attribute with this name, and optionally with this namespace.
60    * @param name The name of the attribute that will be retrieved.
61    * @param ns_prefix Namespace prefix.
62    * @return The attribute, or <tt>nullptr</tt> if no suitable Attribute was found.
63    *         Is either an AttributeNode*, pointing to an explicitly set
64    *         attribute, or an AttributeDeclaration*, pointing to the declaration
65    *         of an attribute with a default value.
66    */
67   Attribute* get_attribute(const Glib::ustring& name,
68                            const Glib::ustring& ns_prefix = Glib::ustring());
69
70   /** Get the attribute with this name, and optionally with this namespace.
71    * @param name The name of the attribute that will be retrieved.
72    * @param ns_prefix Namespace prefix.
73    * @return The attribute, or <tt>nullptr</tt> if no suitable Attribute was found.
74    *         Is either an AttributeNode*, pointing to an explicitly set
75    *         attribute, or an AttributeDeclaration*, pointing to the declaration
76    *         of an attribute with a default value.
77    */
78   const Attribute* get_attribute(const Glib::ustring& name,
79                                  const Glib::ustring& ns_prefix = Glib::ustring()) const;
80
81   /** Get the value of the attribute with this name, and optionally with this namespace.
82    * For finer control, you might use get_attribute() and use the methods of the Attribute class.
83    * @param name The name of the attribute whose value will be retrieved.
84    * @param ns_prefix Namespace prefix.
85    * @return The text value of the attribute, or an empty string if no such attribute was found.
86    *
87    * @newin{2,20}
88    */
89   Glib::ustring get_attribute_value(const Glib::ustring& name,
90                                     const Glib::ustring& ns_prefix = Glib::ustring()) const;
91
92   /** Set the value of the attribute with this name, and optionally with this namespace.
93    * A matching attribute will be added if no matching attribute already exists.
94    * For finer control, you might want to use get_attribute() and use the methods of the Attribute class.
95    * @param name The name of the attribute whose value will change.
96    * @param value The new value for the attribute
97    * @param ns_prefix Namespace prefix. If the prefix has not been declared then this method will throw an exception.
98    * @return The attribute that was changed, or <tt>nullptr</tt> is no suitable Attribute was found.
99    * @throws xmlpp::exception
100    */
101   Attribute* set_attribute(const Glib::ustring& name, const Glib::ustring& value,
102                            const Glib::ustring& ns_prefix = Glib::ustring());
103
104   /** Remove the attribute with this name, and optionally with this namespace.
105    * @param name The name of the attribute to be removed
106    * @param ns_prefix Namespace prefix. If specified, the attribute will be removed only if the attribute has this namespace.
107    */
108   void remove_attribute(const Glib::ustring& name,
109                         const Glib::ustring& ns_prefix = Glib::ustring());
110
111   /** Add a child element to this node.
112    *
113    * @newin{3,0} Replaces Node::add_child()
114    *
115    * @param name The new node name
116    * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception.
117    * @returns The newly-created element
118    * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared.
119    * @throws xmlpp::internal_error If this node is not an element node,
120    *         or the child node cannot be created.
121    */
122   Element* add_child_element(const Glib::ustring& name,
123     const Glib::ustring& ns_prefix = Glib::ustring());
124
125   /** Add a child element to this node after the specified existing child node.
126    *
127    * @newin{3,0} Replaces Node::add_child()
128    *
129    * @param previous_sibling An existing child node.
130    * @param name The new node name
131    * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception.
132    * @returns The newly-created element
133    * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared.
134    * @throws xmlpp::internal_error If this node is not an element node,
135    *         or the child node cannot be created.
136    */
137   Element* add_child_element(xmlpp::Node* previous_sibling, const Glib::ustring& name,
138     const Glib::ustring& ns_prefix = Glib::ustring());
139
140   /** Add a child element to this node before the specified existing child node.
141    *
142    * @newin{3,0} Replaces Node::add_child_before()
143    *
144    * @param next_sibling An existing child node.
145    * @param name The new node name
146    * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception.
147    * @returns The newly-created element
148    * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared.
149    * @throws xmlpp::internal_error If this node is not an element node,
150    *         or the child node cannot be created.
151    */
152   Element* add_child_element_before(xmlpp::Node* next_sibling, const Glib::ustring& name,
153     const Glib::ustring& ns_prefix = Glib::ustring());
154
155   /** Add a child element to this node.
156    *
157    * @newin{3,0} Replaces Node::add_child_with_new_ns()
158    *
159    * @param name The new node name.
160    * @param ns_uri The namespace to associate with the prefix,
161    *               or to use as the default namespace if no prefix is specified.
162    * @param ns_prefix The prefix of the node's namespace. If no prefix is specified
163    *                  then the namespace URI will be the default namespace.
164    * @returns The newly-created element.
165    * @throws xmlpp::internal_error If this node is not an element node,
166    *         or the child node or the namespace node cannot be created.
167    */
168   Element* add_child_element_with_new_ns(const Glib::ustring& name,
169     const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix = Glib::ustring());
170
171   /** Add a child element to this node after the specified existing child node.
172    *
173    * @newin{3,0} Replaces Node::add_child_with_new_ns()
174    *
175    * @param previous_sibling An existing child node.
176    * @param name The new node name.
177    * @param ns_uri The namespace to associate with the prefix,
178    *               or to use as the default namespace if no prefix is specified.
179    * @param ns_prefix The prefix of the node's namespace. If no prefix is specified
180    *                  then the namespace URI will be the default namespace.
181    * @returns The newly-created element.
182    * @throws xmlpp::internal_error If this node is not an element node,
183    *         or the child node or the namespace node cannot be created.
184    */
185   Element* add_child_element_with_new_ns(xmlpp::Node* previous_sibling, const Glib::ustring& name,
186     const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix = Glib::ustring());
187
188   /** Add a child element to this node before the specified existing child node.
189    *
190    * @newin{3,0} Replaces Node::add_child_before_with_new_ns()
191    *
192    * @param next_sibling An existing child node.
193    * @param name The new node name.
194    * @param ns_uri The namespace to associate with the prefix,
195    *               or to use as the default namespace if no prefix is specified.
196    * @param ns_prefix The prefix of the node's namespace. If no prefix is specified
197    *                  then the namespace URI will be the default namespace.
198    * @returns The newly-created element.
199    * @throws xmlpp::internal_error If this node is not an element node,
200    *         or the child node or the namespace node cannot be created.
201    */
202   Element* add_child_element_before_with_new_ns(xmlpp::Node* next_sibling, const Glib::ustring& name,
203     const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix = Glib::ustring());
204
205   /** Get the first child text content node.
206    * This is a convenience method, meant as an alternative to iterating over all the
207    * child nodes to find the first suitable node and then getting the text directly.
208    * @returns The first text node, if any.
209    *
210    * @newin{3,0} Replaces get_child_text().
211    */
212   TextNode* get_first_child_text();
213
214    /** Get the first child text content node.
215    * This is a convenience method, meant as an alternative to iterating over all the
216    * child nodes to find the first suitable node and then getting the text directly.
217    * @returns The first text node, if any.
218    *
219    * @newin{3,0} Replaces get_child_text().
220    */
221   const TextNode* get_first_child_text() const;
222
223   /** Append a new text node.
224    * @param content The text. This should be unescaped - see ContentNode::set_content().
225    * @returns The new text node.
226    * @throws xmlpp::internal_error
227    */
228   TextNode* add_child_text(const Glib::ustring& content = Glib::ustring());
229
230   /** Add a new text node after the specified existing child node.
231    *
232    * @newin{2,24}
233    *
234    * @param previous_sibling An existing child node.
235    * @param content The text. This should be unescaped - see ContentNode::set_content().
236    * @returns The new text node.
237    * @throws xmlpp::internal_error
238    */
239   TextNode* add_child_text(xmlpp::Node* previous_sibling, const Glib::ustring& content = Glib::ustring());
240
241   /** Add a new text node before the specified existing child node.
242    *
243    * @newin{2,24}
244    *
245    * @param next_sibling An existing child node.
246    * @param content The text. This should be unescaped - see ContentNode::set_content().
247    * @returns The new text node.
248    * @throws xmlpp::internal_error
249    */
250   TextNode* add_child_text_before(xmlpp::Node* next_sibling, const Glib::ustring& content = Glib::ustring());
251
252   /** Set the text of the first text node, adding one if necessary.
253    * This is a convenience method, meant as an alternative to iterating over all the
254    * child nodes to find the first suitable node and then setting the text directly.
255    * @param content The text. This should be unescaped - see ContentNode::set_content().
256    * @throws xmlpp::internal_error
257    *
258    * @newin{3,0} Replaces set_child_text().
259    */
260   void set_first_child_text(const Glib::ustring& content);
261
262   /** Discover whether one of the child nodes is a text node.
263    * This is a convenience method, meant as an alternative to iterating over all the child nodes and examining them directly.
264    * @returns Whether this node has a child text node.
265    */
266   bool has_child_text() const;
267
268   /** Append a new comment node.
269    * @param content The text. This should be unescaped - see ContentNode::set_content().
270    * @returns The new comment node.
271    * @throws xmlpp::internal_error
272    */
273   CommentNode* add_child_comment(const Glib::ustring& content);
274
275   /** Append a new CDATA node.
276    * @param content The raw text.
277    * @returns The new CDATA node.
278    * @throws xmlpp::internal_error
279    */
280   CdataNode* add_child_cdata(const Glib::ustring& content);
281
282   /** Append a new entity reference node.
283    * The reference can be either an entity reference ("name" or "&name;") or
284    * a character reference ("#dec", "#xhex", "&#dec;", or "&#xhex;").
285    *
286    * '&' and ';' are optional. If they exist, they are stripped from the stored
287    * copy of the name. Node::get_name() returns the name without '&' and ';'.
288    * If the Document is written to an XML file, '&' and ';' are written.
289    *
290    * @newin{2,36}
291    *
292    * @param name The name of the entity.
293    * @returns The new entity reference node.
294    * @throws xmlpp::internal_error
295    */
296   EntityReference* add_child_entity_reference(const Glib::ustring& name);
297
298   /** Append a new processing instruction node.
299    *
300    * @newin{2,36}
301    *
302    * @param name The name of the application to which the instruction is directed.
303    * @param content The content of the instruction. This should be unescaped - see ContentNode::set_content().
304    * @returns The new processing instruction node.
305    * @throws xmlpp::internal_error
306    */
307   ProcessingInstructionNode* add_child_processing_instruction(
308     const Glib::ustring& name, const Glib::ustring& content);
309
310 private:
311   Glib::ustring get_namespace_uri_for_prefix(const Glib::ustring& ns_prefix) const;
312
313   ///Create the C instance ready to be added to the parent node.
314   _xmlNode* create_new_child_element_node(const Glib::ustring& name,
315     const Glib::ustring& ns_prefix);
316
317   ///Create the C instance ready to be added to the parent node.
318   _xmlNode* create_new_child_element_node_with_new_ns(const Glib::ustring& name,
319     const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix);
320 };
321
322 } // namespace xmlpp
323
324 #endif //__LIBXMLPP_NODES_ELEMENT_H