OpenShot Library | libopenshot-audio 0.2.0
juce_XmlElement.h
1
2/** @weakgroup juce_core-xml
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 The code included in this file is provided under the terms of the ISC license
15 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16 To use, copy, modify, and/or distribute this software for any purpose with or
17 without fee is hereby granted provided that the above copyright notice and
18 this permission notice appear in all copies.
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29
30//==============================================================================
31/** A handy macro to make it easy to iterate all the child elements in an XmlElement.
32
33 The parentXmlElement should be a reference to the parent XML, and the childElementVariableName
34 will be the name of a pointer to each child element.
35
36 E.g. @code
37 XmlElement* myParentXml = createSomeKindOfXmlDocument();
38
39 forEachXmlChildElement (*myParentXml, child)
40 {
41 if (child->hasTagName ("FOO"))
42 doSomethingWithXmlElement (child);
43 }
44
45 @endcode
46
47 @see forEachXmlChildElementWithTagName
48*/
49#define forEachXmlChildElement(parentXmlElement, childElementVariableName) \
50\
51 for (auto* childElementVariableName = (parentXmlElement).getFirstChildElement(); \
52 childElementVariableName != nullptr; \
53 childElementVariableName = childElementVariableName->getNextElement())
54
55/** A macro that makes it easy to iterate all the child elements of an XmlElement
56 which have a specified tag.
57
58 This does the same job as the forEachXmlChildElement macro, but only for those
59 elements that have a particular tag name.
60
61 The parentXmlElement should be a reference to the parent XML, and the childElementVariableName
62 will be the name of a pointer to each child element. The requiredTagName is the
63 tag name to match.
64
65 E.g. @code
66 XmlElement* myParentXml = createSomeKindOfXmlDocument();
67
68 forEachXmlChildElementWithTagName (*myParentXml, child, "MYTAG")
69 {
70 // the child object is now guaranteed to be a <MYTAG> element..
71 doSomethingWithMYTAGElement (child);
72 }
73
74 @endcode
75
76 @see forEachXmlChildElement
77*/
78#define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \
79\
80 for (auto* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \
81 childElementVariableName != nullptr; \
82 childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName))
83
84
85//==============================================================================
86/** Used to build a tree of elements representing an XML document.
87
88 An XML document can be parsed into a tree of XmlElements, each of which
89 represents an XML tag structure, and which may itself contain other
90 nested elements.
91
92 An XmlElement can also be converted back into a text document, and has
93 lots of useful methods for manipulating its attributes and sub-elements,
94 so XmlElements can actually be used as a handy general-purpose data
95 structure.
96
97 Here's an example of parsing some elements: @code
98 // check we're looking at the right kind of document..
99 if (myElement->hasTagName ("ANIMALS"))
100 {
101 // now we'll iterate its sub-elements looking for 'giraffe' elements..
102 forEachXmlChildElement (*myElement, e)
103 {
104 if (e->hasTagName ("GIRAFFE"))
105 {
106 // found a giraffe, so use some of its attributes..
107
108 String giraffeName = e->getStringAttribute ("name");
109 int giraffeAge = e->getIntAttribute ("age");
110 bool isFriendly = e->getBoolAttribute ("friendly");
111 }
112 }
113 }
114 @endcode
115
116 And here's an example of how to create an XML document from scratch: @code
117 // create an outer node called "ANIMALS"
118 XmlElement animalsList ("ANIMALS");
119
120 for (int i = 0; i < numAnimals; ++i)
121 {
122 // create an inner element..
123 XmlElement* giraffe = new XmlElement ("GIRAFFE");
124
125 giraffe->setAttribute ("name", "nigel");
126 giraffe->setAttribute ("age", 10);
127 giraffe->setAttribute ("friendly", true);
128
129 // ..and add our new element to the parent node
130 animalsList.addChildElement (giraffe);
131 }
132
133 // now we can turn the whole thing into a text document..
134 String myXmlDoc = animalsList.createDocument (String());
135 @endcode
136
137 @see XmlDocument
138
139 @tags{Core}
140*/
142{
143public:
144 //==============================================================================
145 /** Creates an XmlElement with this tag name. */
146 explicit XmlElement (const String& tagName);
147
148 /** Creates an XmlElement with this tag name. */
149 explicit XmlElement (const char* tagName);
150
151 /** Creates an XmlElement with this tag name. */
152 explicit XmlElement (const Identifier& tagName);
153
154 /** Creates an XmlElement with this tag name. */
155 explicit XmlElement (StringRef tagName);
156
157 /** Creates an XmlElement with this tag name. */
159
160 /** Creates a (deep) copy of another element. */
161 XmlElement (const XmlElement&);
162
163 /** Creates a (deep) copy of another element. */
165
166 /** Move assignment operator */
167 XmlElement& operator= (XmlElement&&) noexcept;
168
169 /** Move constructor */
170 XmlElement (XmlElement&&) noexcept;
171
172 /** Deleting an XmlElement will also delete all of its child elements. */
173 ~XmlElement() noexcept;
174
175 //==============================================================================
176 /** Compares two XmlElements to see if they contain the same text and attributes.
177
178 The elements are only considered equivalent if they contain the same attributes
179 with the same values, and have the same sub-nodes.
180
181 @param other the other element to compare to
182 @param ignoreOrderOfAttributes if true, this means that two elements with the
183 same attributes in a different order will be
184 considered the same; if false, the attributes must
185 be in the same order as well
186 */
187 bool isEquivalentTo (const XmlElement* other,
188 bool ignoreOrderOfAttributes) const noexcept;
189
190 //==============================================================================
191 /** Returns an XML text document that represents this element.
192
193 The string returned can be parsed to recreate the same XmlElement that
194 was used to create it.
195
196 @param dtdToUse the DTD to add to the document
197 @param allOnOneLine if true, this means that the document will not contain any
198 linefeeds, so it'll be smaller but not very easy to read.
199 @param includeXmlHeader whether to add the "<?xml version..etc" line at the start of the
200 document
201 @param encodingType the character encoding format string to put into the xml
202 header
203 @param lineWrapLength the line length that will be used before items get placed on
204 a new line. This isn't an absolute maximum length, it just
205 determines how lists of attributes get broken up
206 @see writeToStream, writeToFile
207 */
208 String createDocument (StringRef dtdToUse,
209 bool allOnOneLine = false,
210 bool includeXmlHeader = true,
211 StringRef encodingType = "UTF-8",
212 int lineWrapLength = 60) const;
213
214 /** Writes the document to a stream as UTF-8.
215
216 @param output the stream to write to
217 @param dtdToUse the DTD to add to the document
218 @param allOnOneLine if true, this means that the document will not contain any
219 linefeeds, so it'll be smaller but not very easy to read.
220 @param includeXmlHeader whether to add the "<?xml version..etc" line at the start of the
221 document
222 @param encodingType the character encoding format string to put into the xml
223 header
224 @param lineWrapLength the line length that will be used before items get placed on
225 a new line. This isn't an absolute maximum length, it just
226 determines how lists of attributes get broken up
227 @see writeToFile, createDocument
228 */
229 void writeToStream (OutputStream& output,
231 bool allOnOneLine = false,
232 bool includeXmlHeader = true,
233 StringRef encodingType = "UTF-8",
234 int lineWrapLength = 60) const;
235
236 /** Writes the element to a file as an XML document.
237
238 To improve safety in case something goes wrong while writing the file, this
239 will actually write the document to a new temporary file in the same
240 directory as the destination file, and if this succeeds, it will rename this
241 new file as the destination file (overwriting any existing file that was there).
242
243 @param destinationFile the file to write to. If this already exists, it will be
244 overwritten.
245 @param dtdToUse the DTD to add to the document
246 @param encodingType the character encoding format string to put into the xml
247 header
248 @param lineWrapLength the line length that will be used before items get placed on
249 a new line. This isn't an absolute maximum length, it just
250 determines how lists of attributes get broken up
251 @returns true if the file is written successfully; false if something goes wrong
252 in the process
253 @see createDocument
254 */
255 bool writeToFile (const File& destinationFile,
257 StringRef encodingType = "UTF-8",
258 int lineWrapLength = 60) const;
259
260 //==============================================================================
261 /** Returns this element's tag type name.
262 E.g. for an element such as <MOOSE legs="4" antlers="2">, this would return "MOOSE".
263 @see hasTagName
264 */
265 const String& getTagName() const noexcept { return tagName; }
266
267 /** Returns the namespace portion of the tag-name, or an empty string if none is specified. */
268 String getNamespace() const;
269
270 /** Returns the part of the tag-name that follows any namespace declaration. */
271 String getTagNameWithoutNamespace() const;
272
273 /** Tests whether this element has a particular tag name.
274 @param possibleTagName the tag name you're comparing it with
275 @see getTagName
276 */
277 bool hasTagName (StringRef possibleTagName) const noexcept;
278
279 /** Tests whether this element has a particular tag name, ignoring any XML namespace prefix.
280 So a test for e.g. "xyz" will return true for "xyz" and also "foo:xyz", "bar::xyz", etc.
281 @see getTagName
282 */
283 bool hasTagNameIgnoringNamespace (StringRef possibleTagName) const;
284
285 /** Changes this elements tag name.
286 @see getTagName
287 */
288 void setTagName (StringRef newTagName);
289
290 //==============================================================================
291 /** Returns the number of XML attributes this element contains.
292
293 E.g. for an element such as <MOOSE legs="4" antlers="2">, this would
294 return 2.
295 */
296 int getNumAttributes() const noexcept;
297
298 /** Returns the name of one of the elements attributes.
299
300 E.g. for an element such as <MOOSE legs="4" antlers="2">, then
301 getAttributeName(1) would return "antlers".
302
303 @see getAttributeValue, getStringAttribute
304 */
305 const String& getAttributeName (int attributeIndex) const noexcept;
306
307 /** Returns the value of one of the elements attributes.
308
309 E.g. for an element such as <MOOSE legs="4" antlers="2">, then
310 getAttributeName(1) would return "2".
311
312 @see getAttributeName, getStringAttribute
313 */
314 const String& getAttributeValue (int attributeIndex) const noexcept;
315
316 //==============================================================================
317 // Attribute-handling methods..
318
319 /** Checks whether the element contains an attribute with a certain name. */
320 bool hasAttribute (StringRef attributeName) const noexcept;
321
322 /** Returns the value of a named attribute.
323 @param attributeName the name of the attribute to look up
324 */
325 const String& getStringAttribute (StringRef attributeName) const noexcept;
326
327 /** Returns the value of a named attribute.
328 @param attributeName the name of the attribute to look up
329 @param defaultReturnValue a value to return if the element doesn't have an attribute
330 with this name
331 */
333
334 /** Compares the value of a named attribute with a value passed-in.
335
336 @param attributeName the name of the attribute to look up
337 @param stringToCompareAgainst the value to compare it with
338 @param ignoreCase whether the comparison should be case-insensitive
339 @returns true if the value of the attribute is the same as the string passed-in;
340 false if it's different (or if no such attribute exists)
341 */
342 bool compareAttribute (StringRef attributeName,
344 bool ignoreCase = false) const noexcept;
345
346 /** Returns the value of a named attribute as an integer.
347
348 This will try to find the attribute and convert it to an integer (using
349 the String::getIntValue() method).
350
351 @param attributeName the name of the attribute to look up
352 @param defaultReturnValue a value to return if the element doesn't have an attribute
353 with this name
354 @see setAttribute
355 */
356 int getIntAttribute (StringRef attributeName, int defaultReturnValue = 0) const;
357
358 /** Returns the value of a named attribute as floating-point.
359
360 This will try to find the attribute and convert it to a double (using
361 the String::getDoubleValue() method).
362
363 @param attributeName the name of the attribute to look up
364 @param defaultReturnValue a value to return if the element doesn't have an attribute
365 with this name
366 @see setAttribute
367 */
368 double getDoubleAttribute (StringRef attributeName, double defaultReturnValue = 0.0) const;
369
370 /** Returns the value of a named attribute as a boolean.
371
372 This will try to find the attribute and interpret it as a boolean. To do this,
373 it'll return true if the value is "1", "true", "y", etc, or false for other
374 values.
375
376 @param attributeName the name of the attribute to look up
377 @param defaultReturnValue a value to return if the element doesn't have an attribute
378 with this name
379 */
380 bool getBoolAttribute (StringRef attributeName, bool defaultReturnValue = false) const;
381
382 /** Adds a named attribute to the element.
383
384 If the element already contains an attribute with this name, it's value will
385 be updated to the new value. If there's no such attribute yet, a new one will
386 be added.
387
388 Note that there are other setAttribute() methods that take integers,
389 doubles, etc. to make it easy to store numbers.
390
391 @param attributeName the name of the attribute to set
392 @param newValue the value to set it to
393 @see removeAttribute
394 */
395 void setAttribute (const Identifier& attributeName, const String& newValue);
396
397 /** Adds a named attribute to the element, setting it to an integer value.
398
399 If the element already contains an attribute with this name, it's value will
400 be updated to the new value. If there's no such attribute yet, a new one will
401 be added.
402
403 Note that there are other setAttribute() methods that take integers,
404 doubles, etc. to make it easy to store numbers.
405
406 @param attributeName the name of the attribute to set
407 @param newValue the value to set it to
408 */
409 void setAttribute (const Identifier& attributeName, int newValue);
410
411 /** Adds a named attribute to the element, setting it to a floating-point value.
412
413 If the element already contains an attribute with this name, it's value will
414 be updated to the new value. If there's no such attribute yet, a new one will
415 be added.
416
417 Note that there are other setAttribute() methods that take integers,
418 doubles, etc. to make it easy to store numbers.
419
420 @param attributeName the name of the attribute to set
421 @param newValue the value to set it to
422 */
423 void setAttribute (const Identifier& attributeName, double newValue);
424
425 /** Removes a named attribute from the element.
426
427 @param attributeName the name of the attribute to remove
428 @see removeAllAttributes
429 */
430 void removeAttribute (const Identifier& attributeName) noexcept;
431
432 /** Removes all attributes from this element. */
433 void removeAllAttributes() noexcept;
434
435 //==============================================================================
436 // Child element methods..
437
438 /** Returns the first of this element's sub-elements.
439 see getNextElement() for an example of how to iterate the sub-elements.
440 @see forEachXmlChildElement
441 */
442 XmlElement* getFirstChildElement() const noexcept { return firstChildElement; }
443
444 /** Returns the next of this element's siblings.
445
446 This can be used for iterating an element's sub-elements, e.g.
447 @code
448 XmlElement* child = myXmlDocument->getFirstChildElement();
449
450 while (child != nullptr)
451 {
452 ...do stuff with this child..
453
454 child = child->getNextElement();
455 }
456 @endcode
457
458 Note that when iterating the child elements, some of them might be
459 text elements as well as XML tags - use isTextElement() to work this
460 out.
461
462 Also, it's much easier and neater to use this method indirectly via the
463 forEachXmlChildElement macro.
464
465 @returns the sibling element that follows this one, or a nullptr if
466 this is the last element in its parent
467
468 @see getNextElement, isTextElement, forEachXmlChildElement
469 */
470 inline XmlElement* getNextElement() const noexcept { return nextListItem; }
471
472 /** Returns the next of this element's siblings which has the specified tag
473 name.
474
475 This is like getNextElement(), but will scan through the list until it
476 finds an element with the given tag name.
477
478 @see getNextElement, forEachXmlChildElementWithTagName
479 */
480 XmlElement* getNextElementWithTagName (StringRef requiredTagName) const;
481
482 /** Returns the number of sub-elements in this element.
483 @see getChildElement
484 */
485 int getNumChildElements() const noexcept;
486
487 /** Returns the sub-element at a certain index.
488
489 It's not very efficient to iterate the sub-elements by index - see
490 getNextElement() for an example of how best to iterate.
491
492 @returns the n'th child of this element, or nullptr if the index is out-of-range
493 @see getNextElement, isTextElement, getChildByName
494 */
495 XmlElement* getChildElement (int index) const noexcept;
496
497 /** Returns the first sub-element with a given tag-name.
498
499 @param tagNameToLookFor the tag name of the element you want to find
500 @returns the first element with this tag name, or nullptr if none is found
501 @see getNextElement, isTextElement, getChildElement, getChildByAttribute
502 */
504
505 /** Returns the first sub-element which has an attribute that matches the given value.
506
507 @param attributeName the name of the attribute to check
508 @param attributeValue the target value of the attribute
509 @returns the first element with this attribute value, or nullptr if none is found
510 @see getChildByName
511 */
512 XmlElement* getChildByAttribute (StringRef attributeName,
514
515 //==============================================================================
516 /** Appends an element to this element's list of children.
517
518 Child elements are deleted automatically when their parent is deleted, so
519 make sure the object that you pass in will not be deleted by anything else,
520 and make sure it's not already the child of another element.
521
522 Note that due to the XmlElement using a singly-linked-list, prependChildElement()
523 is an O(1) operation, but addChildElement() is an O(N) operation - so if
524 you're adding large number of elements, you may prefer to do so in reverse order!
525
526 @see getFirstChildElement, getNextElement, getNumChildElements,
527 getChildElement, removeChildElement
528 */
529 void addChildElement (XmlElement* newChildElement) noexcept;
530
531 /** Inserts an element into this element's list of children.
532
533 Child elements are deleted automatically when their parent is deleted, so
534 make sure the object that you pass in will not be deleted by anything else,
535 and make sure it's not already the child of another element.
536
537 @param newChildElement the element to add
538 @param indexToInsertAt the index at which to insert the new element - if this is
539 below zero, it will be added to the end of the list
540 @see addChildElement, insertChildElement
541 */
542 void insertChildElement (XmlElement* newChildElement,
544
545 /** Inserts an element at the beginning of this element's list of children.
546
547 Child elements are deleted automatically when their parent is deleted, so
548 make sure the object that you pass in will not be deleted by anything else,
549 and make sure it's not already the child of another element.
550
551 Note that due to the XmlElement using a singly-linked-list, prependChildElement()
552 is an O(1) operation, but addChildElement() is an O(N) operation - so if
553 you're adding large number of elements, you may prefer to do so in reverse order!
554
555 @see addChildElement, insertChildElement
556 */
557 void prependChildElement (XmlElement* newChildElement) noexcept;
558
559 /** Creates a new element with the given name and returns it, after adding it
560 as a child element.
561
562 This is a handy method that means that instead of writing this:
563 @code
564 XmlElement* newElement = new XmlElement ("foobar");
565 myParentElement->addChildElement (newElement);
566 @endcode
567
568 ..you could just write this:
569 @code
570 XmlElement* newElement = myParentElement->createNewChildElement ("foobar");
571 @endcode
572 */
573 XmlElement* createNewChildElement (StringRef tagName);
574
575 /** Replaces one of this element's children with another node.
576
577 If the current element passed-in isn't actually a child of this element,
578 this will return false and the new one won't be added. Otherwise, the
579 existing element will be deleted, replaced with the new one, and it
580 will return true.
581 */
582 bool replaceChildElement (XmlElement* currentChildElement,
584
585 /** Removes a child element.
586
587 @param childToRemove the child to look for and remove
588 @param shouldDeleteTheChild if true, the child will be deleted, if false it'll
589 just remove it
590 */
591 void removeChildElement (XmlElement* childToRemove,
593
594 /** Deletes all the child elements in the element.
595 @see removeChildElement, deleteAllChildElementsWithTagName
596 */
597 void deleteAllChildElements() noexcept;
598
599 /** Deletes all the child elements with a given tag name.
600 @see removeChildElement
601 */
602 void deleteAllChildElementsWithTagName (StringRef tagName) noexcept;
603
604 /** Returns true if the given element is a child of this one. */
605 bool containsChildElement (const XmlElement* possibleChild) const noexcept;
606
607 /** Recursively searches all sub-elements of this one, looking for an element
608 which is the direct parent of the specified element.
609
610 Because elements don't store a pointer to their parent, if you have one
611 and need to find its parent, the only way to do so is to exhaustively
612 search the whole tree for it.
613
614 If the given child is found somewhere in this element's hierarchy, then
615 this method will return its parent. If not, it will return nullptr.
616 */
617 XmlElement* findParentElementOf (const XmlElement* childToSearchFor) noexcept;
618
619 //==============================================================================
620 /** Sorts the child elements using a comparator.
621
622 This will use a comparator object to sort the elements into order. The object
623 passed must have a method of the form:
624 @code
625 int compareElements (const XmlElement* first, const XmlElement* second);
626 @endcode
627
628 ..and this method must return:
629 - a value of < 0 if the first comes before the second
630 - a value of 0 if the two objects are equivalent
631 - a value of > 0 if the second comes before the first
632
633 To improve performance, the compareElements() method can be declared as static or const.
634
635 @param comparator the comparator to use for comparing elements.
636 @param retainOrderOfEquivalentItems if this is true, then items which the comparator
637 says are equivalent will be kept in the order in which they
638 currently appear in the array. This is slower to perform, but
639 may be important in some cases. If it's false, a faster algorithm
640 is used, but equivalent elements may be rearranged.
641 */
643 void sortChildElements (ElementComparator& comparator,
645 {
646 auto num = getNumChildElements();
647
648 if (num > 1)
649 {
651 getChildElementsAsArray (elems);
652 sortArray (comparator, (XmlElement**) elems, 0, num - 1, retainOrderOfEquivalentItems);
653 reorderChildElements (elems, num);
654 }
655 }
656
657 //==============================================================================
658 /** Returns true if this element is a section of text.
659
660 Elements can either be an XML tag element or a section of text, so this
661 is used to find out what kind of element this one is.
662
663 @see getAllText, addTextElement, deleteAllTextElements
664 */
665 bool isTextElement() const noexcept;
666
667 /** Returns the text for a text element.
668
669 Note that if you have an element like this:
670
671 @code<xyz>hello</xyz>@endcode
672
673 then calling getText on the "xyz" element won't return "hello", because that is
674 actually stored in a special text sub-element inside the xyz element. To get the
675 "hello" string, you could either call getText on the (unnamed) sub-element, or
676 use getAllSubText() to do this automatically.
677
678 Note that leading and trailing whitespace will be included in the string - to remove
679 if, just call String::trim() on the result.
680
681 @see isTextElement, getAllSubText, getChildElementAllSubText
682 */
683 const String& getText() const noexcept;
684
685 /** Sets the text in a text element.
686
687 Note that this is only a valid call if this element is a text element. If it's
688 not, then no action will be performed. If you're trying to add text inside a normal
689 element, you probably want to use addTextElement() instead.
690 */
691 void setText (const String& newText);
692
693 /** Returns all the text from this element's child nodes.
694
695 This iterates all the child elements and when it finds text elements,
696 it concatenates their text into a big string which it returns.
697
698 E.g. @code<xyz>hello <x>there</x> world</xyz>@endcode
699 if you called getAllSubText on the "xyz" element, it'd return "hello there world".
700
701 Note that leading and trailing whitespace will be included in the string - to remove
702 if, just call String::trim() on the result.
703
704 @see isTextElement, getChildElementAllSubText, getText, addTextElement
705 */
706 String getAllSubText() const;
707
708 /** Returns all the sub-text of a named child element.
709
710 If there is a child element with the given tag name, this will return
711 all of its sub-text (by calling getAllSubText() on it). If there is
712 no such child element, this will return the default string passed-in.
713
714 @see getAllSubText
715 */
716 String getChildElementAllSubText (StringRef childTagName,
718
719 /** Appends a section of text to this element.
720 @see isTextElement, getText, getAllSubText
721 */
722 void addTextElement (const String& text);
723
724 /** Removes all the text elements from this element.
725 @see isTextElement, getText, getAllSubText, addTextElement
726 */
727 void deleteAllTextElements() noexcept;
728
729 /** Creates a text element that can be added to a parent element. */
730 static XmlElement* createTextElement (const String& text);
731
732 /** Checks if a given string is a valid XML name */
733 static bool isValidXmlName (StringRef possibleName) noexcept;
734
735 //==============================================================================
736private:
737 struct XmlAttributeNode
738 {
739 XmlAttributeNode (const XmlAttributeNode&) noexcept;
740 XmlAttributeNode (const Identifier&, const String&) noexcept;
742
744 Identifier name;
745 String value;
746
747 private:
748 XmlAttributeNode& operator= (const XmlAttributeNode&) = delete;
749 };
750
751 friend class XmlDocument;
752 friend class LinkedListPointer<XmlAttributeNode>;
753 friend class LinkedListPointer<XmlElement>;
754 friend class LinkedListPointer<XmlElement>::Appender;
755 friend class NamedValueSet;
756
757 LinkedListPointer<XmlElement> nextListItem;
758 LinkedListPointer<XmlElement> firstChildElement;
759 LinkedListPointer<XmlAttributeNode> attributes;
760 String tagName;
761
762 XmlElement (int) noexcept;
763 void copyChildrenAndAttributesFrom (const XmlElement&);
764 void writeElementAsText (OutputStream&, int indentationLevel, int lineWrapLength) const;
765 void getChildElementsAsArray (XmlElement**) const noexcept;
766 void reorderChildElements (XmlElement**, int) noexcept;
767 XmlAttributeNode* getAttribute (StringRef) const noexcept;
768
769 // Sigh.. L"" or _T("") string literals are problematic in general, and really inappropriate
770 // for XML tags. Use a UTF-8 encoded literal instead, or if you're really determined to use
771 // UTF-16, cast it to a String and use the other constructor.
772 XmlElement (const wchar_t*) = delete;
773
774 JUCE_LEAK_DETECTOR (XmlElement)
775};
776
777} // namespace juce
778
779/** @}*/
Holds a resizable array of primitive or copy-by-value objects.
Definition juce_Array.h:60
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
Represents a local file or directory.
Definition juce_File.h:45
Represents a string identifier, designed for accessing properties by name.
The base class for streams that write data to some kind of destination.
A simple class for holding temporary references to a string literal or String.
The JUCE String class!
Definition juce_String.h:43
Used to build a tree of elements representing an XML document.
XmlElement * getNextElement() const noexcept
Returns the next of this element's siblings.
const String & getTagName() const noexcept
Returns this element's tag type name.
#define JUCE_API
This macro is added to all JUCE public class declarations.