OpenShot Library | OpenShotAudio  0.2.1
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 
27 namespace 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 textual XML
134  auto xmlString = animalsList.toString();
135  @endcode
136 
137  @see parseXML, parseXMLIfTagMatches, XmlDocument
138 
139  @tags{Core}
140 */
142 {
143 public:
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. */
164  XmlElement& operator= (const XmlElement&);
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  /** A struct containing options for formatting the text when representing an
192  XML element as a string.
193  */
194  struct TextFormat
195  {
196  /** Default constructor. */
197  TextFormat();
198 
199  String dtd; /**< If supplied, this DTD will be added to the document. */
200  String customHeader; /**< If supplied, this header will be used (and customEncoding & addDefaultHeader will be ignored). */
201  String customEncoding; /**< If not empty and addDefaultHeader is true, this will be set as the encoding. Otherwise, a default of "UTF-8" will be used */
202  bool addDefaultHeader = true; /**< If true, a default header will be generated; otherwise just bare XML will be emitted. */
203  int lineWrapLength = 60; /**< A maximum line length before wrapping is done. (If newLineChars is nullptr, this is ignored) */
204  const char* newLineChars = "\r\n"; /**< Allows the newline characters to be set. If you set this to nullptr, then the whole XML document will be placed on a single line. */
205 
206  TextFormat singleLine() const; /**< returns a copy of this format with newLineChars set to nullptr. */
207  TextFormat withoutHeader() const; /**< returns a copy of this format with the addDefaultHeader flag set to false. */
208  };
209 
210  /** Returns a text version of this XML element.
211  If your intention is to write the XML to a file or stream, it's probably more efficient to
212  use writeTo() instead of creating an intermediate string.
213  @see writeTo
214  */
215  String toString (const TextFormat& format = {}) const;
216 
217  /** Writes the document to a stream as UTF-8.
218  @see writeTo, toString
219  */
220  void writeTo (OutputStream& output, const TextFormat& format = {}) const;
221 
222  /** Writes the document to a file as UTF-8.
223  @see writeTo, toString
224  */
225  bool writeTo (const File& destinationFile, const TextFormat& format = {}) const;
226 
227  //==============================================================================
228  /** Returns this element's tag type name.
229  E.g. for an element such as <MOOSE legs="4" antlers="2">, this would return "MOOSE".
230  @see hasTagName
231  */
232  const String& getTagName() const noexcept { return tagName; }
233 
234  /** Returns the namespace portion of the tag-name, or an empty string if none is specified. */
235  String getNamespace() const;
236 
237  /** Returns the part of the tag-name that follows any namespace declaration. */
238  String getTagNameWithoutNamespace() const;
239 
240  /** Tests whether this element has a particular tag name.
241  @param possibleTagName the tag name you're comparing it with
242  @see getTagName
243  */
244  bool hasTagName (StringRef possibleTagName) const noexcept;
245 
246  /** Tests whether this element has a particular tag name, ignoring any XML namespace prefix.
247  So a test for e.g. "xyz" will return true for "xyz" and also "foo:xyz", "bar::xyz", etc.
248  @see getTagName
249  */
250  bool hasTagNameIgnoringNamespace (StringRef possibleTagName) const;
251 
252  /** Changes this elements tag name.
253  @see getTagName
254  */
255  void setTagName (StringRef newTagName);
256 
257  //==============================================================================
258  /** Returns the number of XML attributes this element contains.
259 
260  E.g. for an element such as <MOOSE legs="4" antlers="2">, this would
261  return 2.
262  */
263  int getNumAttributes() const noexcept;
264 
265  /** Returns the name of one of the elements attributes.
266 
267  E.g. for an element such as <MOOSE legs="4" antlers="2">, then
268  getAttributeName(1) would return "antlers".
269 
270  @see getAttributeValue, getStringAttribute
271  */
272  const String& getAttributeName (int attributeIndex) const noexcept;
273 
274  /** Returns the value of one of the elements attributes.
275 
276  E.g. for an element such as <MOOSE legs="4" antlers="2">, then
277  getAttributeName(1) would return "2".
278 
279  @see getAttributeName, getStringAttribute
280  */
281  const String& getAttributeValue (int attributeIndex) const noexcept;
282 
283  //==============================================================================
284  // Attribute-handling methods..
285 
286  /** Checks whether the element contains an attribute with a certain name. */
287  bool hasAttribute (StringRef attributeName) const noexcept;
288 
289  /** Returns the value of a named attribute.
290  @param attributeName the name of the attribute to look up
291  */
292  const String& getStringAttribute (StringRef attributeName) const noexcept;
293 
294  /** Returns the value of a named attribute.
295  @param attributeName the name of the attribute to look up
296  @param defaultReturnValue a value to return if the element doesn't have an attribute
297  with this name
298  */
299  String getStringAttribute (StringRef attributeName, const String& defaultReturnValue) const;
300 
301  /** Compares the value of a named attribute with a value passed-in.
302 
303  @param attributeName the name of the attribute to look up
304  @param stringToCompareAgainst the value to compare it with
305  @param ignoreCase whether the comparison should be case-insensitive
306  @returns true if the value of the attribute is the same as the string passed-in;
307  false if it's different (or if no such attribute exists)
308  */
309  bool compareAttribute (StringRef attributeName,
310  StringRef stringToCompareAgainst,
311  bool ignoreCase = false) const noexcept;
312 
313  /** Returns the value of a named attribute as an integer.
314 
315  This will try to find the attribute and convert it to an integer (using
316  the String::getIntValue() method).
317 
318  @param attributeName the name of the attribute to look up
319  @param defaultReturnValue a value to return if the element doesn't have an attribute
320  with this name
321  @see setAttribute
322  */
323  int getIntAttribute (StringRef attributeName, int defaultReturnValue = 0) const;
324 
325  /** Returns the value of a named attribute as floating-point.
326 
327  This will try to find the attribute and convert it to a double (using
328  the String::getDoubleValue() method).
329 
330  @param attributeName the name of the attribute to look up
331  @param defaultReturnValue a value to return if the element doesn't have an attribute
332  with this name
333  @see setAttribute
334  */
335  double getDoubleAttribute (StringRef attributeName, double defaultReturnValue = 0.0) const;
336 
337  /** Returns the value of a named attribute as a boolean.
338 
339  This will try to find the attribute and interpret it as a boolean. To do this,
340  it'll return true if the value is "1", "true", "y", etc, or false for other
341  values.
342 
343  @param attributeName the name of the attribute to look up
344  @param defaultReturnValue a value to return if the element doesn't have an attribute
345  with this name
346  */
347  bool getBoolAttribute (StringRef attributeName, bool defaultReturnValue = false) const;
348 
349  /** Adds a named attribute to the element.
350 
351  If the element already contains an attribute with this name, it's value will
352  be updated to the new value. If there's no such attribute yet, a new one will
353  be added.
354 
355  Note that there are other setAttribute() methods that take integers,
356  doubles, etc. to make it easy to store numbers.
357 
358  @param attributeName the name of the attribute to set
359  @param newValue the value to set it to
360  @see removeAttribute
361  */
362  void setAttribute (const Identifier& attributeName, const String& newValue);
363 
364  /** Adds a named attribute to the element, setting it to an integer value.
365 
366  If the element already contains an attribute with this name, it's value will
367  be updated to the new value. If there's no such attribute yet, a new one will
368  be added.
369 
370  Note that there are other setAttribute() methods that take integers,
371  doubles, etc. to make it easy to store numbers.
372 
373  @param attributeName the name of the attribute to set
374  @param newValue the value to set it to
375  */
376  void setAttribute (const Identifier& attributeName, int newValue);
377 
378  /** Adds a named attribute to the element, setting it to a floating-point value.
379 
380  If the element already contains an attribute with this name, it's value will
381  be updated to the new value. If there's no such attribute yet, a new one will
382  be added.
383 
384  Note that there are other setAttribute() methods that take integers,
385  doubles, etc. to make it easy to store numbers.
386 
387  @param attributeName the name of the attribute to set
388  @param newValue the value to set it to
389  */
390  void setAttribute (const Identifier& attributeName, double newValue);
391 
392  /** Removes a named attribute from the element.
393 
394  @param attributeName the name of the attribute to remove
395  @see removeAllAttributes
396  */
397  void removeAttribute (const Identifier& attributeName) noexcept;
398 
399  /** Removes all attributes from this element. */
400  void removeAllAttributes() noexcept;
401 
402  //==============================================================================
403  // Child element methods..
404 
405  /** Returns the first of this element's sub-elements.
406  see getNextElement() for an example of how to iterate the sub-elements.
407  @see forEachXmlChildElement
408  */
409  XmlElement* getFirstChildElement() const noexcept { return firstChildElement; }
410 
411  /** Returns the next of this element's siblings.
412 
413  This can be used for iterating an element's sub-elements, e.g.
414  @code
415  XmlElement* child = myXmlDocument->getFirstChildElement();
416 
417  while (child != nullptr)
418  {
419  ...do stuff with this child..
420 
421  child = child->getNextElement();
422  }
423  @endcode
424 
425  Note that when iterating the child elements, some of them might be
426  text elements as well as XML tags - use isTextElement() to work this
427  out.
428 
429  Also, it's much easier and neater to use this method indirectly via the
430  forEachXmlChildElement macro.
431 
432  @returns the sibling element that follows this one, or a nullptr if
433  this is the last element in its parent
434 
435  @see getNextElement, isTextElement, forEachXmlChildElement
436  */
437  inline XmlElement* getNextElement() const noexcept { return nextListItem; }
438 
439  /** Returns the next of this element's siblings which has the specified tag
440  name.
441 
442  This is like getNextElement(), but will scan through the list until it
443  finds an element with the given tag name.
444 
445  @see getNextElement, forEachXmlChildElementWithTagName
446  */
447  XmlElement* getNextElementWithTagName (StringRef requiredTagName) const;
448 
449  /** Returns the number of sub-elements in this element.
450  @see getChildElement
451  */
452  int getNumChildElements() const noexcept;
453 
454  /** Returns the sub-element at a certain index.
455 
456  It's not very efficient to iterate the sub-elements by index - see
457  getNextElement() for an example of how best to iterate.
458 
459  @returns the n'th child of this element, or nullptr if the index is out-of-range
460  @see getNextElement, isTextElement, getChildByName
461  */
462  XmlElement* getChildElement (int index) const noexcept;
463 
464  /** Returns the first sub-element with a given tag-name.
465 
466  @param tagNameToLookFor the tag name of the element you want to find
467  @returns the first element with this tag name, or nullptr if none is found
468  @see getNextElement, isTextElement, getChildElement, getChildByAttribute
469  */
470  XmlElement* getChildByName (StringRef tagNameToLookFor) const noexcept;
471 
472  /** Returns the first sub-element which has an attribute that matches the given value.
473 
474  @param attributeName the name of the attribute to check
475  @param attributeValue the target value of the attribute
476  @returns the first element with this attribute value, or nullptr if none is found
477  @see getChildByName
478  */
479  XmlElement* getChildByAttribute (StringRef attributeName,
480  StringRef attributeValue) const noexcept;
481 
482  //==============================================================================
483  /** Appends an element to this element's list of children.
484 
485  Child elements are deleted automatically when their parent is deleted, so
486  make sure the object that you pass in will not be deleted by anything else,
487  and make sure it's not already the child of another element.
488 
489  Note that due to the XmlElement using a singly-linked-list, prependChildElement()
490  is an O(1) operation, but addChildElement() is an O(N) operation - so if
491  you're adding large number of elements, you may prefer to do so in reverse order!
492 
493  @see getFirstChildElement, getNextElement, getNumChildElements,
494  getChildElement, removeChildElement
495  */
496  void addChildElement (XmlElement* newChildElement) noexcept;
497 
498  /** Inserts an element into this element's list of children.
499 
500  Child elements are deleted automatically when their parent is deleted, so
501  make sure the object that you pass in will not be deleted by anything else,
502  and make sure it's not already the child of another element.
503 
504  @param newChildElement the element to add
505  @param indexToInsertAt the index at which to insert the new element - if this is
506  below zero, it will be added to the end of the list
507  @see addChildElement, insertChildElement
508  */
509  void insertChildElement (XmlElement* newChildElement,
510  int indexToInsertAt) noexcept;
511 
512  /** Inserts an element at the beginning of this element's list of children.
513 
514  Child elements are deleted automatically when their parent is deleted, so
515  make sure the object that you pass in will not be deleted by anything else,
516  and make sure it's not already the child of another element.
517 
518  Note that due to the XmlElement using a singly-linked-list, prependChildElement()
519  is an O(1) operation, but addChildElement() is an O(N) operation - so if
520  you're adding large number of elements, you may prefer to do so in reverse order!
521 
522  @see addChildElement, insertChildElement
523  */
524  void prependChildElement (XmlElement* newChildElement) noexcept;
525 
526  /** Creates a new element with the given name and returns it, after adding it
527  as a child element.
528 
529  This is a handy method that means that instead of writing this:
530  @code
531  XmlElement* newElement = new XmlElement ("foobar");
532  myParentElement->addChildElement (newElement);
533  @endcode
534 
535  ..you could just write this:
536  @code
537  XmlElement* newElement = myParentElement->createNewChildElement ("foobar");
538  @endcode
539  */
540  XmlElement* createNewChildElement (StringRef tagName);
541 
542  /** Replaces one of this element's children with another node.
543 
544  If the current element passed-in isn't actually a child of this element,
545  this will return false and the new one won't be added. Otherwise, the
546  existing element will be deleted, replaced with the new one, and it
547  will return true.
548  */
549  bool replaceChildElement (XmlElement* currentChildElement,
550  XmlElement* newChildNode) noexcept;
551 
552  /** Removes a child element.
553 
554  @param childToRemove the child to look for and remove
555  @param shouldDeleteTheChild if true, the child will be deleted, if false it'll
556  just remove it
557  */
558  void removeChildElement (XmlElement* childToRemove,
559  bool shouldDeleteTheChild) noexcept;
560 
561  /** Deletes all the child elements in the element.
562  @see removeChildElement, deleteAllChildElementsWithTagName
563  */
564  void deleteAllChildElements() noexcept;
565 
566  /** Deletes all the child elements with a given tag name.
567  @see removeChildElement
568  */
569  void deleteAllChildElementsWithTagName (StringRef tagName) noexcept;
570 
571  /** Returns true if the given element is a child of this one. */
572  bool containsChildElement (const XmlElement* possibleChild) const noexcept;
573 
574  /** Recursively searches all sub-elements of this one, looking for an element
575  which is the direct parent of the specified element.
576 
577  Because elements don't store a pointer to their parent, if you have one
578  and need to find its parent, the only way to do so is to exhaustively
579  search the whole tree for it.
580 
581  If the given child is found somewhere in this element's hierarchy, then
582  this method will return its parent. If not, it will return nullptr.
583  */
584  XmlElement* findParentElementOf (const XmlElement* childToSearchFor) noexcept;
585 
586  //==============================================================================
587  /** Sorts the child elements using a comparator.
588 
589  This will use a comparator object to sort the elements into order. The object
590  passed must have a method of the form:
591  @code
592  int compareElements (const XmlElement* first, const XmlElement* second);
593  @endcode
594 
595  ..and this method must return:
596  - a value of < 0 if the first comes before the second
597  - a value of 0 if the two objects are equivalent
598  - a value of > 0 if the second comes before the first
599 
600  To improve performance, the compareElements() method can be declared as static or const.
601 
602  @param comparator the comparator to use for comparing elements.
603  @param retainOrderOfEquivalentItems if this is true, then items which the comparator
604  says are equivalent will be kept in the order in which they
605  currently appear in the array. This is slower to perform, but
606  may be important in some cases. If it's false, a faster algorithm
607  is used, but equivalent elements may be rearranged.
608  */
609  template <class ElementComparator>
610  void sortChildElements (ElementComparator& comparator,
611  bool retainOrderOfEquivalentItems = false)
612  {
613  auto num = getNumChildElements();
614 
615  if (num > 1)
616  {
617  HeapBlock<XmlElement*> elems (num);
618  getChildElementsAsArray (elems);
619  sortArray (comparator, (XmlElement**) elems, 0, num - 1, retainOrderOfEquivalentItems);
620  reorderChildElements (elems, num);
621  }
622  }
623 
624  //==============================================================================
625  /** Returns true if this element is a section of text.
626 
627  Elements can either be an XML tag element or a section of text, so this
628  is used to find out what kind of element this one is.
629 
630  @see getAllText, addTextElement, deleteAllTextElements
631  */
632  bool isTextElement() const noexcept;
633 
634  /** Returns the text for a text element.
635 
636  Note that if you have an element like this:
637 
638  @code<xyz>hello</xyz>@endcode
639 
640  then calling getText on the "xyz" element won't return "hello", because that is
641  actually stored in a special text sub-element inside the xyz element. To get the
642  "hello" string, you could either call getText on the (unnamed) sub-element, or
643  use getAllSubText() to do this automatically.
644 
645  Note that leading and trailing whitespace will be included in the string - to remove
646  if, just call String::trim() on the result.
647 
648  @see isTextElement, getAllSubText, getChildElementAllSubText
649  */
650  const String& getText() const noexcept;
651 
652  /** Sets the text in a text element.
653 
654  Note that this is only a valid call if this element is a text element. If it's
655  not, then no action will be performed. If you're trying to add text inside a normal
656  element, you probably want to use addTextElement() instead.
657  */
658  void setText (const String& newText);
659 
660  /** Returns all the text from this element's child nodes.
661 
662  This iterates all the child elements and when it finds text elements,
663  it concatenates their text into a big string which it returns.
664 
665  E.g. @code<xyz>hello <x>there</x> world</xyz>@endcode
666  if you called getAllSubText on the "xyz" element, it'd return "hello there world".
667 
668  Note that leading and trailing whitespace will be included in the string - to remove
669  if, just call String::trim() on the result.
670 
671  @see isTextElement, getChildElementAllSubText, getText, addTextElement
672  */
673  String getAllSubText() const;
674 
675  /** Returns all the sub-text of a named child element.
676 
677  If there is a child element with the given tag name, this will return
678  all of its sub-text (by calling getAllSubText() on it). If there is
679  no such child element, this will return the default string passed-in.
680 
681  @see getAllSubText
682  */
683  String getChildElementAllSubText (StringRef childTagName,
684  const String& defaultReturnValue) const;
685 
686  /** Appends a section of text to this element.
687  @see isTextElement, getText, getAllSubText
688  */
689  void addTextElement (const String& text);
690 
691  /** Removes all the text elements from this element.
692  @see isTextElement, getText, getAllSubText, addTextElement
693  */
694  void deleteAllTextElements() noexcept;
695 
696  /** Creates a text element that can be added to a parent element. */
697  static XmlElement* createTextElement (const String& text);
698 
699  /** Checks if a given string is a valid XML name */
700  static bool isValidXmlName (StringRef possibleName) noexcept;
701 
702  //==============================================================================
703  /** This has been deprecated in favour of the toString() method. */
704  JUCE_DEPRECATED (String createDocument (StringRef dtdToUse,
705  bool allOnOneLine = false,
706  bool includeXmlHeader = true,
707  StringRef encodingType = "UTF-8",
708  int lineWrapLength = 60) const);
709 
710  /** This has been deprecated in favour of the writeTo() method. */
711  JUCE_DEPRECATED (void writeToStream (OutputStream& output,
712  StringRef dtdToUse,
713  bool allOnOneLine = false,
714  bool includeXmlHeader = true,
715  StringRef encodingType = "UTF-8",
716  int lineWrapLength = 60) const);
717 
718  /** This has been deprecated in favour of the writeTo() method. */
719  JUCE_DEPRECATED (bool writeToFile (const File& destinationFile,
720  StringRef dtdToUse,
721  StringRef encodingType = "UTF-8",
722  int lineWrapLength = 60) const);
723 
724  //==============================================================================
725 private:
726  struct XmlAttributeNode
727  {
728  XmlAttributeNode (const XmlAttributeNode&) noexcept;
729  XmlAttributeNode (const Identifier&, const String&) noexcept;
731 
733  Identifier name;
734  String value;
735 
736  private:
737  XmlAttributeNode& operator= (const XmlAttributeNode&) = delete;
738  };
739 
740  friend class XmlDocument;
741  friend class LinkedListPointer<XmlAttributeNode>;
742  friend class LinkedListPointer<XmlElement>;
743  friend class LinkedListPointer<XmlElement>::Appender;
744  friend class NamedValueSet;
745 
746  LinkedListPointer<XmlElement> nextListItem, firstChildElement;
747  LinkedListPointer<XmlAttributeNode> attributes;
748  String tagName;
749 
750  XmlElement (int) noexcept;
751  void copyChildrenAndAttributesFrom (const XmlElement&);
752  void writeElementAsText (OutputStream&, int, int, const char*) const;
753  void getChildElementsAsArray (XmlElement**) const noexcept;
754  void reorderChildElements (XmlElement**, int) noexcept;
755  XmlAttributeNode* getAttribute (StringRef) const noexcept;
756 
757  // Sigh.. L"" or _T("") string literals are problematic in general, and really inappropriate
758  // for XML tags. Use a UTF-8 encoded literal instead, or if you're really determined to use
759  // UTF-16, cast it to a String and use the other constructor.
760  XmlElement (const wchar_t*) = delete;
761 
762  JUCE_LEAK_DETECTOR (XmlElement)
763 };
764 
765 } // namespace juce
766 
767 /** @}*/
Parses a text-based XML document and creates an XmlElement object from it.
#define JUCE_API
This macro is added to all JUCE public class declarations.
String customEncoding
If not empty and addDefaultHeader is true, this will be set as the encoding.
Represents a string identifier, designed for accessing properties by name.
A simple class for holding temporary references to a string literal or String.
Used to build a tree of elements representing an XML document.
Very simple container class to hold a pointer to some data on the heap.
The JUCE String class!
Definition: juce_String.h:42
String dtd
If supplied, this DTD will be added to the document.
Holds a set of named var objects.
XmlElement * getNextElement() const noexcept
Returns the next of this element&#39;s siblings.
void sortChildElements(ElementComparator &comparator, bool retainOrderOfEquivalentItems=false)
Sorts the child elements using a comparator.
Represents a local file or directory.
Definition: juce_File.h:44
The base class for streams that write data to some kind of destination.
XmlElement * getFirstChildElement() const noexcept
Returns the first of this element&#39;s sub-elements.
String customHeader
If supplied, this header will be used (and customEncoding & addDefaultHeader will be ignored)...
A struct containing options for formatting the text when representing an XML element as a string...
const String & getTagName() const noexcept
Returns this element&#39;s tag type name.
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...