Loading...
Searching...
No Matches
juce_XmlElement.h
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
class JUCE_API XmlElement
{
public:
//==============================================================================
explicit XmlElement (const String& tagName);
explicit XmlElement (const char* tagName);
explicit XmlElement (const Identifier& tagName);
explicit XmlElement (StringRef tagName);
XmlElement (String::CharPointerType tagNameBegin, String::CharPointerType tagNameEnd);
XmlElement (const XmlElement&);
XmlElement& operator= (const XmlElement&);
XmlElement& operator= (XmlElement&&) noexcept;
XmlElement (XmlElement&&) noexcept;
~XmlElement() noexcept;
//==============================================================================
bool isEquivalentTo (const XmlElement* other,
bool ignoreOrderOfAttributes) const noexcept;
//==============================================================================
struct TextFormat
{
TextFormat();
String dtd;
String customHeader;
String customEncoding;
bool addDefaultHeader = true;
int lineWrapLength = 60;
const char* newLineChars = "\r\n";
[[nodiscard]] TextFormat singleLine() const;
[[nodiscard]] TextFormat withoutHeader() const;
};
String toString (const TextFormat& format = {}) const;
void writeTo (OutputStream& output, const TextFormat& format = {}) const;
bool writeTo (const File& destinationFile, const TextFormat& format = {}) const;
//==============================================================================
const String& getTagName() const noexcept { return tagName; }
String getNamespace() const;
String getTagNameWithoutNamespace() const;
bool hasTagName (StringRef possibleTagName) const noexcept;
bool hasTagNameIgnoringNamespace (StringRef possibleTagName) const;
void setTagName (StringRef newTagName);
//==============================================================================
int getNumAttributes() const noexcept;
const String& getAttributeName (int attributeIndex) const noexcept;
const String& getAttributeValue (int attributeIndex) const noexcept;
//==============================================================================
// Attribute-handling methods..
bool hasAttribute (StringRef attributeName) const noexcept;
const String& getStringAttribute (StringRef attributeName) const noexcept;
String getStringAttribute (StringRef attributeName, const String& defaultReturnValue) const;
bool compareAttribute (StringRef attributeName,
StringRef stringToCompareAgainst,
bool ignoreCase = false) const noexcept;
int getIntAttribute (StringRef attributeName, int defaultReturnValue = 0) const;
double getDoubleAttribute (StringRef attributeName, double defaultReturnValue = 0.0) const;
bool getBoolAttribute (StringRef attributeName, bool defaultReturnValue = false) const;
void setAttribute (const Identifier& attributeName, const String& newValue);
void setAttribute (const Identifier& attributeName, int newValue);
void setAttribute (const Identifier& attributeName, double newValue);
void removeAttribute (const Identifier& attributeName) noexcept;
void removeAllAttributes() noexcept;
//==============================================================================
// Child element methods..
XmlElement* getFirstChildElement() const noexcept { return firstChildElement; }
inline XmlElement* getNextElement() const noexcept { return nextListItem; }
XmlElement* getNextElementWithTagName (StringRef requiredTagName) const;
int getNumChildElements() const noexcept;
XmlElement* getChildElement (int index) const noexcept;
XmlElement* getChildByName (StringRef tagNameToLookFor) const noexcept;
XmlElement* getChildByAttribute (StringRef attributeName,
StringRef attributeValue) const noexcept;
//==============================================================================
void addChildElement (XmlElement* newChildElement) noexcept;
void insertChildElement (XmlElement* newChildElement,
int indexToInsertAt) noexcept;
void prependChildElement (XmlElement* newChildElement) noexcept;
XmlElement* createNewChildElement (StringRef tagName);
bool replaceChildElement (XmlElement* currentChildElement,
XmlElement* newChildNode) noexcept;
void removeChildElement (XmlElement* childToRemove,
bool shouldDeleteTheChild) noexcept;
void deleteAllChildElements() noexcept;
void deleteAllChildElementsWithTagName (StringRef tagName) noexcept;
bool containsChildElement (const XmlElement* possibleChild) const noexcept;
XmlElement* findParentElementOf (const XmlElement* childToSearchFor) noexcept;
//==============================================================================
template <class ElementComparator>
void sortChildElements (ElementComparator& comparator,
bool retainOrderOfEquivalentItems = false)
{
auto num = getNumChildElements();
if (num > 1)
{
HeapBlock<XmlElement*> elems (num);
getChildElementsAsArray (elems);
sortArray (comparator, (XmlElement**) elems, 0, num - 1, retainOrderOfEquivalentItems);
reorderChildElements (elems, num);
}
}
//==============================================================================
bool isTextElement() const noexcept;
const String& getText() const noexcept;
void setText (const String& newText);
String getAllSubText() const;
String getChildElementAllSubText (StringRef childTagName,
const String& defaultReturnValue) const;
void addTextElement (const String& text);
void deleteAllTextElements() noexcept;
static XmlElement* createTextElement (const String& text);
static bool isValidXmlName (StringRef possibleName) noexcept;
private:
//==============================================================================
struct GetNextElement
{
XmlElement* getNext (const XmlElement& e) const { return e.getNextElement(); }
};
struct GetNextElementWithTagName
{
GetNextElementWithTagName() = default;
explicit GetNextElementWithTagName (String n) : name (std::move (n)) {}
XmlElement* getNext (const XmlElement& e) const { return e.getNextElementWithTagName (name); }
String name;
};
//==============================================================================
template <typename Traits>
class Iterator : private Traits
{
public:
using difference_type = ptrdiff_t;
using value_type = XmlElement*;
using pointer = const value_type*;
using reference = value_type;
using iterator_category = std::input_iterator_tag;
Iterator() = default;
template <typename... Args>
Iterator (XmlElement* e, Args&&... args)
: Traits (std::forward<Args> (args)...), element (e) {}
Iterator begin() const { return *this; }
Iterator end() const { return Iterator{}; }
bool operator== (const Iterator& other) const { return element == other.element; }
bool operator!= (const Iterator& other) const { return ! operator== (other); }
reference operator*() const { return element; }
pointer operator->() const { return &element; }
Iterator& operator++()
{
element = Traits::getNext (*element);
return *this;
}
Iterator operator++ (int)
{
auto copy = *this;
++(*this);
return copy;
}
private:
value_type element = nullptr;
};
public:
//==============================================================================
Iterator<GetNextElement> getChildIterator() const
{
return Iterator<GetNextElement> { getFirstChildElement() };
}
Iterator<GetNextElementWithTagName> getChildWithTagNameIterator (StringRef name) const
{
return Iterator<GetNextElementWithTagName> { getChildByName (name), name };
}
#ifndef DOXYGEN
[[deprecated]] void macroBasedForLoop() const noexcept {}
[[deprecated ("This has been deprecated in favour of the toString method.")]]
String createDocument (StringRef dtdToUse,
bool allOnOneLine = false,
bool includeXmlHeader = true,
StringRef encodingType = "UTF-8",
int lineWrapLength = 60) const;
[[deprecated ("This has been deprecated in favour of the writeTo method.")]]
void writeToStream (OutputStream& output,
StringRef dtdToUse,
bool allOnOneLine = false,
bool includeXmlHeader = true,
StringRef encodingType = "UTF-8",
int lineWrapLength = 60) const;
[[deprecated ("This has been deprecated in favour of the writeTo method.")]]
bool writeToFile (const File& destinationFile,
StringRef dtdToUse,
StringRef encodingType = "UTF-8",
int lineWrapLength = 60) const;
#endif
private:
//==============================================================================
struct XmlAttributeNode
{
XmlAttributeNode (const XmlAttributeNode&) noexcept;
XmlAttributeNode (const Identifier&, const String&) noexcept;
XmlAttributeNode (String::CharPointerType, String::CharPointerType);
LinkedListPointer<XmlAttributeNode> nextListItem;
Identifier name;
String value;
private:
XmlAttributeNode& operator= (const XmlAttributeNode&) = delete;
};
friend class XmlDocument;
friend class LinkedListPointer<XmlAttributeNode>;
friend class LinkedListPointer<XmlElement>;
friend class LinkedListPointer<XmlElement>::Appender;
friend class NamedValueSet;
LinkedListPointer<XmlElement> nextListItem, firstChildElement;
LinkedListPointer<XmlAttributeNode> attributes;
String tagName;
XmlElement (int) noexcept;
void copyChildrenAndAttributesFrom (const XmlElement&);
void writeElementAsText (OutputStream&, int, int, const char*) const;
void getChildElementsAsArray (XmlElement**) const noexcept;
void reorderChildElements (XmlElement**, int) noexcept;
XmlAttributeNode* getAttribute (StringRef) const noexcept;
// Sigh.. L"" or _T ("") string literals are problematic in general, and really inappropriate
// for XML tags. Use a UTF-8 encoded literal instead, or if you're really determined to use
// UTF-16, cast it to a String and use the other constructor.
XmlElement (const wchar_t*) = delete;
JUCE_LEAK_DETECTOR (XmlElement)
};
//==============================================================================
#ifndef DOXYGEN
#define forEachXmlChildElement(parentXmlElement, childElementVariableName) \
for (auto* (childElementVariableName) : ((parentXmlElement).macroBasedForLoop(), (parentXmlElement).getChildIterator()))
#define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \
for (auto* (childElementVariableName) : ((parentXmlElement).macroBasedForLoop(), (parentXmlElement).getChildWithTagNameIterator ((requiredTagName))))
#endif
} // namespace juce
juce::HeapBlock
Definition juce_HeapBlock.h:87
juce::Identifier
Definition juce_Identifier.h:39
juce::OutputStream
Definition juce_OutputStream.h:38
juce::StringRef
Definition juce_StringRef.h:62
juce::String
Definition juce_String.h:53
juce::XmlElement
Definition juce_XmlElement.h:83
juce::XmlElement::getNumChildElements
int getNumChildElements() const noexcept
Definition juce_XmlElement.cpp:668
juce::XmlElement::XmlElement
XmlElement(const String &tagName)
Definition juce_XmlElement.cpp:76
juce::XmlElement::getChildByName
XmlElement * getChildByName(StringRef tagNameToLookFor) const noexcept
Definition juce_XmlElement.cpp:678
juce::XmlElement::getNextElement
XmlElement * getNextElement() const noexcept
Definition juce_XmlElement.h:379
juce::XmlElement::toString
String toString(const TextFormat &format={}) const
Definition juce_XmlElement.cpp:352
juce::XmlElement::sortChildElements
void sortChildElements(ElementComparator &comparator, bool retainOrderOfEquivalentItems=false)
Definition juce_XmlElement.h:552
juce::XmlElement::getChildWithTagNameIterator
Iterator< GetNextElementWithTagName > getChildWithTagNameIterator(StringRef name) const
Definition juce_XmlElement.h:730
juce::XmlElement::isEquivalentTo
bool isEquivalentTo(const XmlElement *other, bool ignoreOrderOfAttributes) const noexcept
Definition juce_XmlElement.cpp:771
juce::XmlElement::getChildIterator
Iterator< GetNextElement > getChildIterator() const
Definition juce_XmlElement.h:715
juce::XmlElement::getTagName
const String & getTagName() const noexcept
Definition juce_XmlElement.h:173
juce::XmlElement::getFirstChildElement
XmlElement * getFirstChildElement() const noexcept
Definition juce_XmlElement.h:351
juce::XmlElement::TextFormat
Definition juce_XmlElement.h:136
juce::XmlElement::TextFormat::customEncoding
String customEncoding
Definition juce_XmlElement.h:142
juce::XmlElement::TextFormat::withoutHeader
TextFormat withoutHeader() const
Definition juce_XmlElement.cpp:345
juce::XmlElement::TextFormat::addDefaultHeader
bool addDefaultHeader
Definition juce_XmlElement.h:143
juce::XmlElement::TextFormat::dtd
String dtd
Definition juce_XmlElement.h:140
juce::XmlElement::TextFormat::newLineChars
const char * newLineChars
Definition juce_XmlElement.h:145
juce::XmlElement::TextFormat::customHeader
String customHeader
Definition juce_XmlElement.h:141
juce::XmlElement::TextFormat::singleLine
TextFormat singleLine() const
Definition juce_XmlElement.cpp:338
juce::XmlElement::TextFormat::lineWrapLength
int lineWrapLength
Definition juce_XmlElement.h:144
juce::XmlElement::TextFormat::TextFormat
TextFormat()
Definition juce_XmlElement.cpp:336