3039 lines
89 KiB
C++
3039 lines
89 KiB
C++
// ____ ______ __
|
|
// / __ \ / ____// /
|
|
// / /_/ // / / /
|
|
// / ____// /___ / /___ PixInsight Class Library
|
|
// /_/ \____//_____/ PCL 2.4.23
|
|
// ----------------------------------------------------------------------------
|
|
// pcl/XML.h - Released 2022-03-12T18:59:29Z
|
|
// ----------------------------------------------------------------------------
|
|
// This file is part of the PixInsight Class Library (PCL).
|
|
// PCL is a multiplatform C++ framework for development of PixInsight modules.
|
|
//
|
|
// Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved.
|
|
//
|
|
// Redistribution and use in both source and binary forms, with or without
|
|
// modification, is permitted provided that the following conditions are met:
|
|
//
|
|
// 1. All redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. All redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
|
|
// of their contributors, may be used to endorse or promote products derived
|
|
// from this software without specific prior written permission. For written
|
|
// permission, please contact info@pixinsight.com.
|
|
//
|
|
// 4. All products derived from this software, in any form whatsoever, must
|
|
// reproduce the following acknowledgment in the end-user documentation
|
|
// and/or other materials provided with the product:
|
|
//
|
|
// "This product is based on software from the PixInsight project, developed
|
|
// by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
|
|
//
|
|
// Alternatively, if that is where third-party acknowledgments normally
|
|
// appear, this acknowledgment must be reproduced in the product itself.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
// EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
|
|
// INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
|
|
// DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#ifndef __PCL_XML_h
|
|
#define __PCL_XML_h
|
|
|
|
/// \file pcl/XML.h
|
|
|
|
#include <pcl/Defs.h>
|
|
|
|
#include <pcl/Exception.h>
|
|
#include <pcl/ReferenceArray.h>
|
|
#include <pcl/String.h>
|
|
|
|
namespace pcl
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \defgroup xml_parsing_and_generation XML Document Parsing and Generation
|
|
*/
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class PCL_CLASS XMLDocument;
|
|
class PCL_CLASS XMLElement;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XML
|
|
* \brief Utility functions and data for %XML document parsing and generation
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XML
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Default constructor. This constructor is disabled because %XML is not an
|
|
* instantiable class.
|
|
*/
|
|
XML() = delete;
|
|
|
|
/*!
|
|
* Copy constructor. This constructor is disabled because %XML is not an
|
|
* instantiable class.
|
|
*/
|
|
XML( const XML& ) = delete;
|
|
|
|
/*!
|
|
* Copy assignment. This operator is disabled because %XML is not an
|
|
* instantiable class.
|
|
*/
|
|
XML& operator =( const XML& ) = delete;
|
|
|
|
/*!
|
|
* Destructor. This destructor is disabled because %XML is not an
|
|
* instantiable class.
|
|
*/
|
|
~XML() = delete;
|
|
|
|
/*!
|
|
* Returns true iff the specified character \a c is either a white space
|
|
* (\#x20) or a tabulator (#9) character.
|
|
*/
|
|
template <typename T>
|
|
static bool IsWhiteSpaceChar( T c )
|
|
{
|
|
return c == 0x20 || c == 9;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff the specified character \a c is either a line feed
|
|
* (\#x0A) or a carriage return (#0D) control character.
|
|
*/
|
|
template <typename T>
|
|
static bool IsLineBreakChar( T c )
|
|
{
|
|
return c == 0x0A || c == 0x0D;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff the specified character \a c is an %XML space character:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-S
|
|
*/
|
|
template <typename T>
|
|
static bool IsSpaceChar( T c )
|
|
{
|
|
return IsWhiteSpaceChar( c ) || IsLineBreakChar( c );
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff the specified character \a c is an %XML NameStartChar:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-NameStartChar
|
|
*/
|
|
template <typename T>
|
|
static bool IsNameStartChar( T c )
|
|
{
|
|
return c >= T( 'a' ) && c <= T( 'z' )
|
|
|| c >= T( 'A' ) && c <= T( 'Z' )
|
|
|| c == T( '_' )
|
|
|| c == T( ':' )
|
|
|| c >= 0xC0 && c <= 0xD6
|
|
|| c >= 0xD8 && c <= 0xF6
|
|
|| c >= 0xF8 && c <= 0x2FF
|
|
|| c >= 0x370 && c <= 0x37D
|
|
|| c >= 0x37F && c <= 0x1FFF
|
|
|| c >= 0x200C && c <= 0x200D
|
|
|| c >= 0x2070 && c <= 0x218F
|
|
|| c >= 0x2C00 && c <= 0x2FEF
|
|
|| c >= 0x3001 && c <= 0xD7FF
|
|
|| c >= 0xF900 && c <= 0xFDCF
|
|
|| c >= 0xFDF0 && c <= 0xFFFD
|
|
|| uint32( c ) >= 0x10000 && uint32( c ) <= 0xEFFFF;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff the specified character \a c is an %XML NameChar:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-NameChar
|
|
*/
|
|
template <typename T>
|
|
static bool IsNameChar( T c )
|
|
{
|
|
return IsNameStartChar( c )
|
|
|| c >= T( '0' ) && c <= T( '9' )
|
|
|| c == T( '-' )
|
|
|| c == T( '.' )
|
|
|| c == 0xB7
|
|
|| c >= 0x0300 && c <= 0x036F
|
|
|| c >= 0x203F && c <= 0x2040;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff the specified character \a c is an %XML RestrictedChar:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-RestrictedChar
|
|
*/
|
|
template <typename T>
|
|
static bool IsRestrictedChar( T c )
|
|
{
|
|
return c >= 0x00 && c <= 0x08
|
|
|| c >= 0x0B && c <= 0x0C
|
|
|| c >= 0x0E && c <= 0x1F
|
|
|| c >= 0x7F && c <= 0x84
|
|
|| c >= 0x86 && c <= 0x9F;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff the specified \a name is a valid %XML qualified element
|
|
* or attribute name:
|
|
*
|
|
* https://www.w3.org/TR/xml-names/#ns-qualnames
|
|
*/
|
|
static bool IsValidName( const String& name )
|
|
{
|
|
if ( !name.IsEmpty() )
|
|
if ( IsNameStartChar( *name ) )
|
|
for ( String::const_iterator i = name.Begin(); ; )
|
|
{
|
|
if ( ++i == name.End() )
|
|
return true;
|
|
if ( !IsNameChar( *i ) )
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*!
|
|
* Returns a copy of the text fragment defined by the range [i,j) of string
|
|
* iterators with all leading and trailing space characters removed.
|
|
*/
|
|
static String TrimmedSpaces( String::const_iterator i, String::const_iterator j );
|
|
|
|
/*!
|
|
* Returns a copy of the specified \a text with all leading and trailing
|
|
* space characters removed.
|
|
*/
|
|
static String TrimmedSpaces( const String& text );
|
|
|
|
/*!
|
|
* Returns a copy of the text fragment defined by the range [i,j) of string
|
|
* iterators with all sequences of one or more space characters replaced
|
|
* with single white space characters (\#x20).
|
|
*/
|
|
static String CollapsedSpaces( String::const_iterator i, String::const_iterator j );
|
|
|
|
/*!
|
|
* Returns a copy of the specified \a text with all sequences of one or more
|
|
* space characters replaced with single white space characters (\#x20).
|
|
*/
|
|
static String CollapsedSpaces( const String& text );
|
|
|
|
/*!
|
|
* Returns a copy of the text fragment defined by the range [i,j) of string
|
|
* iterators with all %XML references replaced by their corresponding UTF-16
|
|
* characters.
|
|
*
|
|
* Both entity and character references are decoded by this function. For
|
|
* entity references, the entire set of %XML reference names is supported:
|
|
*
|
|
* http://www.w3.org/TR/xml-entity-names/
|
|
*
|
|
* Character references are interpreted as defined in the %XML
|
|
* specification:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-CharRef
|
|
*/
|
|
static String DecodedText( String::const_iterator i, String::const_iterator j );
|
|
|
|
/*!
|
|
* Returns a copy of the specified \a text with all %XML references replaced
|
|
* by their corresponding UTF-16 characters.
|
|
*
|
|
* See DecodedText( String::const_iterator, String::const_iterator ) for a
|
|
* detailed description.
|
|
*/
|
|
static String DecodedText( const String& text );
|
|
|
|
/*!
|
|
* Returns a copy of the text fragment defined by the range [i,j) of string
|
|
* iterators with all occurences of '&', '<', '>' and '"' replaced with the
|
|
* entity references "amp", "lt", "gt" and "quot", respectively. If \a apos
|
|
* is true, single quotes will also be replaced with "apos" entities.
|
|
*/
|
|
static String EncodedText( String::const_iterator i, String::const_iterator j, bool apos = true )
|
|
{
|
|
return EncodedText( String( i, j ), apos );
|
|
}
|
|
|
|
/*!
|
|
* Returns a copy of the specified \a text with all occurences of '&', '<',
|
|
* '>' and '"' replaced with the entity references "amp", "lt", "gt" and
|
|
* "quot", respectively. If \a apos is true, single quotes will also be
|
|
* replaced with "apos" entities.
|
|
*/
|
|
static String EncodedText( const String& text, bool apos = true );
|
|
|
|
/*!
|
|
* Returns the Unicode value (encoded as UTF-16) corresponding to an %XML
|
|
* reference defined by the range [i,j) of string iterators:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-Reference
|
|
*
|
|
* Both entity and character references are decoded by this function. For
|
|
* entity references, the entire set of %XML reference names is supported:
|
|
*
|
|
* http://www.w3.org/TR/xml-entity-names/
|
|
*
|
|
* Character references are interpreted as defined in the %XML
|
|
* specification:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-CharRef
|
|
*/
|
|
static String ReferenceValue( String::const_iterator i, String::const_iterator j );
|
|
|
|
/*!
|
|
* Returns the Unicode value (encoded as UTF-16) corresponding to the
|
|
* specified %XML \a reference.
|
|
*
|
|
* See ReferenceValue( String::const_iterator, String::const_iterator ) for
|
|
* a detailed description.
|
|
*/
|
|
static String ReferenceValue( const String& reference )
|
|
{
|
|
return ReferenceValue( reference.Begin(), reference.End() );
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLComponent
|
|
* \brief Root base class of all %XML document components
|
|
*
|
|
* %XMLComponent supports the hierarchical structure of an %XML document by
|
|
* implementing the basic concept of <em>parent element</em>.
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
* \sa XMLNode
|
|
*/
|
|
class PCL_CLASS XMLComponent
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Default constructor. Constructs a default %XMLComment object with no
|
|
* parent element.
|
|
*/
|
|
XMLComponent() = default;
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLComponent( const XMLComponent& ) = default;
|
|
|
|
/*!
|
|
* Returns a pointer to the parent %XML element of this component, or
|
|
* \c nullptr if this object has no parent element.
|
|
*/
|
|
XMLElement* ParentElement() const
|
|
{
|
|
return m_parent;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this is a top-level component. Top-level document
|
|
* components have no parent elements.
|
|
*/
|
|
bool IsTopLevel() const
|
|
{
|
|
return m_parent == nullptr;
|
|
}
|
|
|
|
private:
|
|
|
|
XMLElement* m_parent = nullptr;
|
|
|
|
friend class XMLElement;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \namespace pcl::XMLNodeType
|
|
* \brief %XML document node types
|
|
*
|
|
* <table border="1" cellpadding="4" cellspacing="0">
|
|
* <tr><td>XMLNodeType::Undefined</td> <td>Undefined %XML node type.</td></tr>
|
|
* <tr><td>XMLNodeType::ChildNode</td> <td>Signals a child %XML document node - for internal use only.</td></tr>
|
|
* <tr><td>XMLNodeType::Unknown</td> <td>Represents an unsupported %XML node type.</td></tr>
|
|
* <tr><td>XMLNodeType::Element</td> <td>An %XML element.</td></tr>
|
|
* <tr><td>XMLNodeType::Text</td> <td>A text block inside an element's contents.</td></tr>
|
|
* <tr><td>XMLNodeType::CDATA</td> <td>A CDATA section.</td></tr>
|
|
* <tr><td>XMLNodeType::ProcessingInstructions</td> <td>A processing instructions (PI) section.</td></tr>
|
|
* <tr><td>XMLNodeType::PI</td> <td>A synonym to ProcessingInstructions.</td></tr>
|
|
* <tr><td>XMLNodeType::Comment</td> <td>A comment block.</td></tr>
|
|
* </table>
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
namespace XMLNodeType
|
|
{
|
|
enum mask_type
|
|
{
|
|
Undefined = 0x00000000,
|
|
ChildNode = 0x80000000,
|
|
Unknown = 0x10000000,
|
|
Element = 0x00000001,
|
|
Text = 0x00000002,
|
|
CDATA = 0x00000004,
|
|
ProcessingInstructions = 0x00000008,
|
|
Comment = 0x00000010
|
|
};
|
|
|
|
/*!
|
|
* Returns the name of the specified %XML node \a type ("element", "text",
|
|
* "comment", etc).
|
|
*/
|
|
String AsString( mask_type type );
|
|
}
|
|
|
|
/*!
|
|
* \class pcl::XMLNodeTypes
|
|
* \brief A collection of %XML node types
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
typedef Flags<XMLNodeType::mask_type> XMLNodeTypes;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \struct XMLNodeLocation
|
|
* \brief Source code location of a parsed %XML document node
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
struct XMLNodeLocation
|
|
{
|
|
/*!
|
|
* Zero-based text line number where a parsed node has been identified in
|
|
* an %XML document, or -1 if text location information is not available.
|
|
*/
|
|
int64 line = 0;
|
|
|
|
/*!
|
|
* Zero-based text column number, counted from the starting character of a
|
|
* text line, where a parsed node has been identified in an %XML document.
|
|
* This member is -1 if text location information is not available.
|
|
*
|
|
* Note that the value stored in this field is actually a character index,
|
|
* not necessarily a valid text column number. It is an actual column number
|
|
* only if the corresponding line of text does not contain tabulator
|
|
* characters (\#x9). If there are tabulators, there is usually no one-to-one
|
|
* correspondence between characters and represented text columns.
|
|
*/
|
|
int64 column = 0;
|
|
|
|
/*!
|
|
* Default constructor. Initializes the line and column members to -1,
|
|
* signaling an undefined source code location.
|
|
*/
|
|
XMLNodeLocation() = default;
|
|
|
|
/*!
|
|
* Constructs an %XMLNodeLocation object with the specified zero-based text
|
|
* line and column numbers.
|
|
*/
|
|
XMLNodeLocation( int line_, int column_ )
|
|
: line( line_ )
|
|
, column( column_ )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLNodeLocation( const XMLNodeLocation& ) = default;
|
|
|
|
/*!
|
|
* Returns a string representation of this %XMLNodeLocation object in the
|
|
* form " (line=n offset=m)", where n and m are, respectively, the one-based
|
|
* line number and zero-based text character offset transported by this
|
|
* object. This representation is suitable to be included directly in
|
|
* warning or error messages generated by parsers.
|
|
*
|
|
* The line number token won't be generated if the text line number is
|
|
* undefined (< 0) in this object. Similarly, the offset token won't be
|
|
* generated if the column member is < 0. If no location information is
|
|
* available, this member function returns an empty string.
|
|
*/
|
|
String ToString() const;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLNode
|
|
* \brief Abstract base class of all %XML document node classes
|
|
*
|
|
* %XML document nodes can be elements, text, CDATA sections, processing
|
|
* instructions, comments, and unknown special elements. This class extends the
|
|
* XMLComponent root base class to implement %XML document node classification
|
|
* and serialization.
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLNode : public XMLComponent
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Represents the type of an %XML document node. Supported/valid node types
|
|
* are defined in the XMLNodeType namespace.
|
|
*/
|
|
typedef XMLNodeType::mask_type node_type;
|
|
|
|
/*!
|
|
* Default constructor. Constructs a default %XMLNode object of the
|
|
* specified \a type, with no parent element and undefined source code
|
|
* location.
|
|
*/
|
|
XMLNode( node_type type )
|
|
: m_type( type )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*
|
|
* The newly constructed node will be an \e orphan object, that is, it will
|
|
* have no parent element even if the source object \a x is a child node.
|
|
* This reflects the fact that document nodes are unique objects.
|
|
*/
|
|
XMLNode( const XMLNode& x )
|
|
: m_type( x.NodeType() )
|
|
, m_location( x.m_location )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Virtual destructor.
|
|
*/
|
|
virtual ~XMLNode()
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this is a child node of an existing %XML element.
|
|
*/
|
|
bool IsChildNode() const
|
|
{
|
|
return m_type.IsFlagSet( XMLNodeType::ChildNode );
|
|
}
|
|
|
|
/*!
|
|
* Returns the type of this %XML document node.
|
|
*/
|
|
node_type NodeType() const
|
|
{
|
|
return static_cast<node_type>( XMLNodeTypes::flag_type( m_type & unsigned( ~XMLNodeType::ChildNode ) ) );
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this node is an %XML element. If this member function
|
|
* returns true, this node can be statically casted to XMLElement.
|
|
*/
|
|
bool IsElement() const
|
|
{
|
|
return NodeType() == XMLNodeType::Element;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this node represents an %XML text block. If this member
|
|
* function returns true, this node can be statically casted to XMLText.
|
|
*/
|
|
bool IsText() const
|
|
{
|
|
return NodeType() == XMLNodeType::Text;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this node represents an %XML comment. If this member
|
|
* function returns true, this node can be statically casted to XMLComment.
|
|
*/
|
|
bool IsComment() const
|
|
{
|
|
return NodeType() == XMLNodeType::Comment;
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) source code location of this node.
|
|
*/
|
|
const XMLNodeLocation& Location() const
|
|
{
|
|
return m_location;
|
|
}
|
|
|
|
/*!
|
|
* Serializes this document node as an %XML fragment encoded in UTF-8.
|
|
*
|
|
* \param text Reference to an 8-bit string to which the UTF-8
|
|
* encoded serialization of this node must be appended.
|
|
*
|
|
* \param autoFormat True if line break characters (\#x0A) and
|
|
* indentation strings must be used to improve readability of
|
|
* the generated %XML code. False if no superfluous white space
|
|
* should be generated.
|
|
*
|
|
* \param indentChar A character used for indentation of generated text
|
|
* lines, when \a autoFormat is true. This parameter should be
|
|
* either a white space (' ' or \#x20) or a tabulator ('\\t' or
|
|
* \#x09) character.
|
|
*
|
|
* \param indentSize Number of \a indentChar characters used for each
|
|
* indentation level, when \a autoFormat is true.
|
|
*
|
|
* \param level Recursion level. A value greater than zero denotes
|
|
* that this function is being called from a parent %XML
|
|
* element. The recursion level determines the number of
|
|
* \a indentChar characters prepended to each text line
|
|
* for indentation, when \a autoFormat is true.
|
|
*/
|
|
virtual void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const = 0;
|
|
|
|
/*!
|
|
* Returns true iff a new line character (\#x0A) can be inserted before
|
|
* serializing this node after the specified \a previous node.
|
|
*/
|
|
virtual bool NLAfter( const XMLNode& previous ) const;
|
|
|
|
private:
|
|
|
|
XMLNodeTypes m_type;
|
|
XMLNodeLocation m_location;
|
|
|
|
friend class XMLDocument;
|
|
friend class XMLElement;
|
|
};
|
|
|
|
/*!
|
|
* \class pcl::XMLNodeList
|
|
* \brief Dynamic list of %XML node objects
|
|
*
|
|
* %XMLNodeList is used as the internal implementation of element child node
|
|
* lists and document node lists. In current PCL versions, %XMLNodeList is a
|
|
* template instantiation of ReferenceArray<> for the XMLNode class.
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
typedef ReferenceArray<XMLNode> XMLNodeList;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLParseError
|
|
* \brief %XML parsing error with automatic text location information
|
|
* generation
|
|
*
|
|
* The %XMLParseError is useful to generate warning and error messages during
|
|
* document parsing tasks, with automatic generation of text location
|
|
* information (when available) and a normalized representation of error
|
|
* messages.
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLParseError : public Error
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs an %XMLParseError object with a reference to an XMLNode
|
|
* instance.
|
|
*
|
|
* \param node Reference to the XMLNode object that has caused the
|
|
* exception.
|
|
*
|
|
* \param whileDoing Identifies the parsing action that was taking place.
|
|
* For example: "Parsing Metadata child Image element".
|
|
*
|
|
* \param whatHappened Describes the error that has been detected. For
|
|
* example: "Missing id attribute".
|
|
*
|
|
* This constructor inserts node location information, if available, and
|
|
* joins the strings appropriately to build an error message.
|
|
*/
|
|
XMLParseError( const XMLNode& node, const String& whileDoing, const String& whatHappened )
|
|
: Error( whileDoing + node.Location().ToString() + ": " + whatHappened )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Constructs an %XMLParseError object with a reference to an
|
|
* XMLNodeLocation instance.
|
|
*
|
|
* \param where Reference to an XMLNodeLocation object to retrieve
|
|
* text location information.
|
|
*
|
|
* \param whileDoing Identifies the parsing action that was taking place.
|
|
* For example: "Parsing Metadata child Image element".
|
|
*
|
|
* \param whatHappened Describes the error that has been detected. For
|
|
* example: "Missing id attribute".
|
|
*
|
|
* This constructor inserts node location information, if available, and
|
|
* joins the strings appropriately to build an error message.
|
|
*/
|
|
XMLParseError( const XMLNodeLocation& where, const String& whileDoing, const String& whatHappened )
|
|
: Error( whileDoing + where.ToString() + ": " + whatHappened )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLParseError( const XMLParseError& ) = default;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLAttribute
|
|
* \brief %XML element attribute
|
|
*
|
|
* The %XMLAttribute class represents an element attribute, as defined by the
|
|
* Attribute construct:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-Attribute
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLAttribute : public XMLComponent
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs an empty %XML attribute. An empty attribute is ignored for
|
|
* inclusion in element attribute lists.
|
|
*/
|
|
XMLAttribute() = default;
|
|
|
|
/*!
|
|
* Constructs a new %XMLAttribute object with the specified qualified
|
|
* \a name and \a value.
|
|
*
|
|
* The specified \a name should be a valid %XML qualified name, as defined
|
|
* by the W3C recommendation:
|
|
*
|
|
* https://www.w3.org/TR/xml-names/#ns-qualnames
|
|
*
|
|
* However, the \a name is not checked for validity by this constructor, for
|
|
* performance reasons. Attribute and element names are verified during the
|
|
* document parsing and generation tasks.
|
|
*/
|
|
XMLAttribute( const String& name, const String& value = String() )
|
|
: m_name( name )
|
|
, m_value( value )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLAttribute( const XMLAttribute& ) = default;
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) qualified name of this attribute.
|
|
*/
|
|
const String& Name() const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) value of this element attribute.
|
|
*/
|
|
const String& Value() const
|
|
{
|
|
return m_value;
|
|
}
|
|
|
|
/*!
|
|
* Sets a new value for this %XML element attribute.
|
|
*/
|
|
void SetValue( const String& text )
|
|
{
|
|
m_value = text;
|
|
}
|
|
|
|
/*!
|
|
* Returns an encoded version of the attribute value. All characters that
|
|
* cannot legally occur in an %XML attribute value are replaced by their
|
|
* corresponding entity references.
|
|
*/
|
|
String EncodedValue() const
|
|
{
|
|
return XML::EncodedText( m_value, false/*apos*/ );
|
|
}
|
|
|
|
/*!
|
|
* Equality operator.
|
|
*
|
|
* Two %XML element attributes are considered equal if their qualified names
|
|
* are identical. Note that this restricts valid attribute comparisons to a
|
|
* particular %XML document.
|
|
*/
|
|
bool operator ==( const XMLAttribute& x ) const
|
|
{
|
|
return m_name == x.m_name;
|
|
}
|
|
|
|
/*!
|
|
* Less-than relational operator.
|
|
*
|
|
* To compare %XML element attributes, only their qualified names are taken
|
|
* into account. Note that this restricts valid attribute comparisons to a
|
|
* particular %XML document.
|
|
*/
|
|
bool operator <( const XMLAttribute& x ) const
|
|
{
|
|
return m_name < x.m_name;
|
|
}
|
|
|
|
private:
|
|
|
|
String m_name;
|
|
String m_value;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLAttributeList
|
|
* \brief Dynamic list of %XML element attributes
|
|
*
|
|
* %XMLAttributeList represents a sequence of %XML element attributes in a
|
|
* start-tag, as defined in the W3C recommendation:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#sec-starttags
|
|
*
|
|
* %XMLAttributeList is internally implemented as a dynamic array of
|
|
* XMLAttribute objects.
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLAttributeList
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Represents the dynamic container class used internally to implement an
|
|
* %XML element attribute list.
|
|
*/
|
|
typedef Array<XMLAttribute> list_implementation;
|
|
|
|
/*!
|
|
* Represents a mutable %XML element attribute list iterator.
|
|
*/
|
|
typedef list_implementation::iterator iterator;
|
|
|
|
/*!
|
|
* Represents an immutable %XML element attribute list iterator.
|
|
*/
|
|
typedef list_implementation::const_iterator const_iterator;
|
|
|
|
/*!
|
|
* Constructs a new %XMLAttributeList object by parsing the specified
|
|
* \a text string.
|
|
*
|
|
* The specified \a text must be a sequence of zero or more Attribute %XML
|
|
* definitions pertaining to a start-tag:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-STag
|
|
*
|
|
* See the Parse() member function for a more detailed description.
|
|
*/
|
|
XMLAttributeList( const String& text )
|
|
{
|
|
Parse( text );
|
|
}
|
|
|
|
/*!
|
|
* Default constructor. Constructs an empty %XML attribute list.
|
|
*/
|
|
XMLAttributeList() = default;
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLAttributeList( const XMLAttributeList& ) = default;
|
|
|
|
/*!
|
|
* Returns the number of element attributes in this list.
|
|
*/
|
|
int Length() const
|
|
{
|
|
return int( m_list.Length() );
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this attribute list is empty.
|
|
*/
|
|
bool IsEmpty() const
|
|
{
|
|
return m_list.IsEmpty();
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the immutable element attribute at the specified
|
|
* zero-based index \a i. No bounds checking is performed: if the specified
|
|
* index is invalid this function invokes undefined behavior.
|
|
*/
|
|
const XMLAttribute& operator []( int i ) const
|
|
{
|
|
return m_list[i];
|
|
}
|
|
|
|
/*!
|
|
* Returns an immutable iterator located at the beginning of this element
|
|
* attribute list.
|
|
*/
|
|
const_iterator Begin() const
|
|
{
|
|
return m_list.Begin();
|
|
}
|
|
|
|
/*!
|
|
* Returns an immutable iterator located at the end of this element
|
|
* attribute list.
|
|
*/
|
|
const_iterator End() const
|
|
{
|
|
return m_list.End();
|
|
}
|
|
|
|
#ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
|
|
/*!
|
|
* STL-compatible iteration. Equivalent to Begin() const.
|
|
*/
|
|
const_iterator begin() const
|
|
{
|
|
return Begin();
|
|
}
|
|
|
|
/*!
|
|
* STL-compatible iteration. Equivalent to End() const.
|
|
*/
|
|
const_iterator end() const
|
|
{
|
|
return End();
|
|
}
|
|
#endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
|
|
|
|
/*!
|
|
* Returns true iff this list contains an element attribute with the
|
|
* specified qualified \a name.
|
|
*/
|
|
bool HasAttribute( const String& name ) const
|
|
{
|
|
return m_list.Contains( name );
|
|
}
|
|
|
|
/*!
|
|
* Returns the value of the element attribute with the specified qualified
|
|
* \a name, or an empty string if this list does not contain such an element
|
|
* attribute.
|
|
*/
|
|
String AttributeValue( const String& name ) const
|
|
{
|
|
const_iterator a = m_list.Search( name );
|
|
return (a != m_list.End()) ? a->Value() : String();
|
|
}
|
|
|
|
/*!
|
|
* Causes this list to contain an %XML element attribute with the specified
|
|
* qualified \a name and \a value.
|
|
*
|
|
* If an attribute with the same qualified \a name already exists in this
|
|
* list, then its value will be changed. Otherwise, a new attribute will be
|
|
* appended to this list.
|
|
*
|
|
* This member function ensures that no %XML element can have two or more
|
|
* attributes with the same qualified name. This constraint is part of the
|
|
* %XML specification:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#sec-starttags
|
|
* https://www.w3.org/TR/xml-names/#scoping-defaulting
|
|
*/
|
|
void SetAttribute( const String& name, const String& value )
|
|
{
|
|
if ( !name.IsEmpty() )
|
|
{
|
|
iterator a = m_list.Search( name );
|
|
if ( a == m_list.End() )
|
|
m_list.Add( XMLAttribute( name, value ) );
|
|
else
|
|
a->SetValue( value );
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* Causes this list to contain the specified %XML element \a attribute.
|
|
*
|
|
* See SetAttribute( const String&, const String& ) for more information.
|
|
*/
|
|
void SetAttribute( const XMLAttribute& attribute )
|
|
{
|
|
if ( !attribute.Name().IsEmpty() )
|
|
{
|
|
iterator a = m_list.Search( attribute );
|
|
if ( a == m_list.End() )
|
|
m_list.Add( attribute );
|
|
else
|
|
*a = attribute;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* Insertion operator. Returns a reference to this object.
|
|
*
|
|
* This operator is equivalent to SetAttribute( const XMLAttribute& ).
|
|
*/
|
|
XMLAttributeList& operator <<( const XMLAttribute& attribute )
|
|
{
|
|
SetAttribute( attribute );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* Causes this list to contain the specified \a list of %XML element
|
|
* attributes.
|
|
*
|
|
* For each attribute in the specified \a list, if an attribute with the
|
|
* same qualified \a name already exists in this list, then its value will
|
|
* be changed. Otherwise, a new attribute will be appended to this list.
|
|
*
|
|
* This member function ensures that no %XML element can have two or more
|
|
* attributes with the same qualified name. This constraint is part of the
|
|
* %XML specification:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#sec-starttags
|
|
* https://www.w3.org/TR/xml-names/#scoping-defaulting
|
|
*/
|
|
void SetAttributes( const XMLAttributeList& list )
|
|
{
|
|
for ( auto a : list )
|
|
SetAttribute( a );
|
|
}
|
|
|
|
/*!
|
|
* Insertion operator. Returns a reference to this object.
|
|
*
|
|
* This operator is equivalent to SetAttributes( const XMLAttributeList& ).
|
|
*/
|
|
XMLAttributeList& operator <<( const XMLAttributeList& list )
|
|
{
|
|
SetAttributes( list );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* Removes the element attribute with the specified qualified \a name, if it
|
|
* exists in this list. If no attribute with the specified \a name exists,
|
|
* this member function has no effect.
|
|
*/
|
|
void RemoveAttribute( const String& name )
|
|
{
|
|
iterator a = m_list.Search( name );
|
|
if ( a != m_list.End() )
|
|
m_list.Remove( a );
|
|
}
|
|
|
|
/*!
|
|
* Removes all element attributes in this list, yielding an empty element
|
|
* attribute list.
|
|
*/
|
|
void Clear()
|
|
{
|
|
m_list.Clear();
|
|
}
|
|
|
|
/*!
|
|
* Sorts the element attributes in this list in ascending order by comparing
|
|
* their qualified names.
|
|
*/
|
|
void Sort()
|
|
{
|
|
m_list.Sort();
|
|
}
|
|
|
|
/*!
|
|
* Parses the specified \a text, encoded as UTF-16, to generate a new list
|
|
* of %XML element attributes.
|
|
*
|
|
* The specified \a text must be a sequence of zero or more Attribute %XML
|
|
* definitions pertaining to a start-tag, as described in the W3C
|
|
* recommendation:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-STag
|
|
*
|
|
* Attribute value normalization is applied to each parsed attribute:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#AVNormalize
|
|
*
|
|
* In attribute values, all entity and character references are decoded. See
|
|
* the XML::DecodedText() static function for more information on reference
|
|
* decoding. Normalization also implies space trimming and compression: all
|
|
* leading and trailing space characters are removed, and all sequences of
|
|
* one or more space characters are replaced by single white space
|
|
* characters (\#x20).
|
|
*/
|
|
void Parse( const String& text );
|
|
|
|
/*!
|
|
* Performs the %XML serialization of this element attribute list and
|
|
* appends it to the specified \a text string, encoded in UTF-8.
|
|
*
|
|
* The generated serialization is a sequence of zero or more Attribute %XML
|
|
* definitions pertaining to a start-tag, as described in the W3C
|
|
* recommendation:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-STag
|
|
*/
|
|
void Serialize( IsoString& text ) const;
|
|
|
|
private:
|
|
|
|
list_implementation m_list;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLElement
|
|
* \brief %XML element
|
|
*
|
|
* The %XMLElement class represents an %XML document element:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#dt-element
|
|
*
|
|
* Elements are the main data holders in the logical design of %XML, following
|
|
* a hierarchical tree structure.
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLElement : public XMLNode
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Represents a mutable child node list iterator.
|
|
*/
|
|
typedef XMLNodeList::iterator iterator;
|
|
|
|
/*!
|
|
* Represents an immutable child node list iterator.
|
|
*/
|
|
typedef XMLNodeList::const_iterator const_iterator;
|
|
|
|
/*!
|
|
* A list of child %XML elements. Implemented as a template instantiation of
|
|
* ReferenceArray<> for the XMLElement class.
|
|
*/
|
|
typedef ReferenceArray<XMLElement> child_element_list;
|
|
|
|
/*!
|
|
* Default constructor. Constructs an uninitialized %XMLElement structure.
|
|
*/
|
|
XMLElement()
|
|
: XMLNode( XMLNodeType::Element )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Constructs an empty %XMLElement object with the specified qualified
|
|
* \a name and \a attributes.
|
|
*/
|
|
XMLElement( const String& name, const XMLAttributeList& attributes = XMLAttributeList() )
|
|
: XMLNode( XMLNodeType::Element )
|
|
, m_name( name )
|
|
, m_attributes( attributes )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Constructs an empty %XMLElement object with the specified qualified
|
|
* \a name and \a attributes, as a child node of the specified \a parent
|
|
* element.
|
|
*/
|
|
XMLElement( XMLElement& parent, const String& name, const XMLAttributeList& attributes = XMLAttributeList() )
|
|
: XMLNode( XMLNodeType::Element )
|
|
, m_name( name )
|
|
, m_attributes( attributes )
|
|
{
|
|
parent.AddChildNode( this );
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor. This constructor is disabled because %XMLElement
|
|
* represents unique objects.
|
|
*/
|
|
XMLElement( const XMLElement& ) = delete;
|
|
|
|
/*!
|
|
* Copy assignment. This operator is disabled because %XMLElement represents
|
|
* unique objects.
|
|
*/
|
|
XMLElement& operator =( const XMLElement& ) = delete;
|
|
|
|
/*!
|
|
* Virtual destructor. If this element contains child nodes, all of them
|
|
* will be destroyed recursively.
|
|
*/
|
|
virtual ~XMLElement()
|
|
{
|
|
DestroyChildNodes();
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this is a root %XML element. A root %XML element has no
|
|
* parent element.
|
|
*
|
|
* Note that this member function can return true in two different
|
|
* situations: when the element has been generated during a document parsing
|
|
* process (in which case this is an actual document root element), and if
|
|
* this object has not been initialized yet (because it has been newly
|
|
* constructed and still has not been associated with an %XML document).
|
|
*/
|
|
bool IsRootElement() const
|
|
{
|
|
return ParentElement() == nullptr;
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) qualified element name.
|
|
*/
|
|
const String& Name() const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/*!
|
|
* Returns a copy of the list of %XML element attributes.
|
|
*/
|
|
XMLAttributeList Attributes() const
|
|
{
|
|
return m_attributes;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this element has one or more attributes defined.
|
|
*/
|
|
bool HasAttributes() const
|
|
{
|
|
return !m_attributes.IsEmpty();
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this element has an attribute with the specified
|
|
* qualified \a name.
|
|
*/
|
|
bool HasAttribute( const String& name ) const
|
|
{
|
|
return m_attributes.HasAttribute( name );
|
|
}
|
|
|
|
/*!
|
|
* Returns the value of the attribute with the specified qualified \a name
|
|
* in this element, or an empty string if this element has no such
|
|
* attribute.
|
|
*/
|
|
String AttributeValue( const String& name ) const
|
|
{
|
|
return m_attributes.AttributeValue( name );
|
|
}
|
|
|
|
/*!
|
|
* Causes this %XML element to contain an attribute with the specified
|
|
* qualified \a name and \a value.
|
|
*
|
|
* If an attribute with the same qualified \a name already exists in this
|
|
* element, then its value will be changed. Otherwise, a new attribute will
|
|
* be created in this element.
|
|
*
|
|
* This member function ensures that no %XML element can have two or more
|
|
* attributes with the same qualified name. This constraint is part of the
|
|
* %XML specification:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#sec-starttags
|
|
* https://www.w3.org/TR/xml-names/#scoping-defaulting
|
|
*/
|
|
void SetAttribute( const String& name, const String& value )
|
|
{
|
|
XMLAttribute a( name, value );
|
|
a.m_parent = this;
|
|
m_attributes.SetAttribute( a );
|
|
}
|
|
|
|
/*!
|
|
* Causes this %XML element to contain the specified \a attribute.
|
|
*
|
|
* See SetAttribute( const String&, const String& ) for more information.
|
|
*/
|
|
void SetAttribute( const XMLAttribute& attribute )
|
|
{
|
|
XMLAttribute a( attribute );
|
|
a.m_parent = this;
|
|
m_attributes.SetAttribute( a );
|
|
}
|
|
|
|
/*!
|
|
* Insertion operator. Returns a reference to this object.
|
|
*
|
|
* This operator is equivalent to SetAttribute( const XMLAttribute& ).
|
|
*/
|
|
XMLElement& operator <<( const XMLAttribute& attribute )
|
|
{
|
|
SetAttribute( attribute );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* Causes this %XML element to contain the specified \a list of attributes.
|
|
*
|
|
* For each attribute in the specified \a list, if an attribute with the
|
|
* same qualified \a name already exists in this element, then its value
|
|
* will be changed. Otherwise, a new attribute will be created in this
|
|
* element.
|
|
*
|
|
* This member function ensures that no %XML element can have two or more
|
|
* attributes with the same qualified name. This constraint is part of the
|
|
* %XML specification:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#sec-starttags
|
|
* https://www.w3.org/TR/xml-names/#scoping-defaulting
|
|
*/
|
|
void SetAttributes( const XMLAttributeList& list )
|
|
{
|
|
for ( auto a : list )
|
|
SetAttribute( a );
|
|
}
|
|
|
|
/*!
|
|
* Insertion operator. Returns a reference to this object.
|
|
*
|
|
* This operator is equivalent to SetAttributes( const XMLAttributeList& ).
|
|
*/
|
|
XMLElement& operator <<( const XMLAttributeList& list )
|
|
{
|
|
SetAttributes( list );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* Removes the attribute with the specified qualified \a name, if it exists
|
|
* in this element. If this element has no attribute with the specified
|
|
* \a name, this member function has no effect.
|
|
*/
|
|
void RemoveAttribute( const String& name )
|
|
{
|
|
m_attributes.RemoveAttribute( name );
|
|
}
|
|
|
|
/*!
|
|
* Removes all existing attributes in this element.
|
|
*/
|
|
void ClearAttributes()
|
|
{
|
|
m_attributes.Clear();
|
|
}
|
|
|
|
/*!
|
|
* Sorts the existing attributes in this element in ascending order by
|
|
* comparing their qualified names.
|
|
*/
|
|
void SortAttributes()
|
|
{
|
|
m_attributes.Sort();
|
|
}
|
|
|
|
/*!
|
|
* Sorts the existing attributes in this element in ascending order.
|
|
* Ordering of elements is defined such that for any pair a, b of
|
|
* XMLAttribute objects in this element, the binary predicate p(a,b) is true
|
|
* iff a precedes b.
|
|
*/
|
|
template <class BP>
|
|
void SortAttributes( BP p )
|
|
{
|
|
m_attributes.Sort( p );
|
|
}
|
|
|
|
/*!
|
|
* Parses the specified \a text, encoded as UTF-16, to generate a new list
|
|
* of attributes in this %XML element. The previous list of attributes, if
|
|
* any, will be replaced by the newly generated list.
|
|
*
|
|
* The specified \a text must be a sequence of zero or more Attribute %XML
|
|
* definitions pertaining to a start-tag, as described in the W3C
|
|
* recommendation:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-STag
|
|
*/
|
|
void ParseAttributes( const String& text )
|
|
{
|
|
XMLAttributeList list( text );
|
|
ClearAttributes();
|
|
SetAttributes( list );
|
|
}
|
|
|
|
/*!
|
|
* Performs the %XML serialization of the attribute list in this element and
|
|
* appends it to the specified \a text string, encoded in UTF-8.
|
|
*
|
|
* The generated serialization is a sequence of zero or more Attribute %XML
|
|
* definitions pertaining to a start-tag, as described in the W3C
|
|
* recommendation:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#NT-STag
|
|
*/
|
|
void SerializeAttributes( IsoString& text ) const
|
|
{
|
|
m_attributes.Serialize( text );
|
|
}
|
|
|
|
/*!
|
|
* Returns the number of child nodes in this %XML element.
|
|
*/
|
|
int ChildCount() const
|
|
{
|
|
return int( m_childNodes.Length() );
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this is an empty %XML element. An empty element has no
|
|
* child nodes.
|
|
*/
|
|
bool IsEmpty() const
|
|
{
|
|
return m_childNodes.IsEmpty();
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the immutable child node at the specified
|
|
* zero-based index \a i. No bounds checking is performed: if the specified
|
|
* index is invalid this function invokes undefined behavior.
|
|
*/
|
|
const XMLNode& operator []( int i ) const
|
|
{
|
|
return m_childNodes[i];
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the immutable first child node in this element. No
|
|
* bounds checking is performed: if this element is empty, this function
|
|
* invokes undefined behavior.
|
|
*/
|
|
const XMLNode& First() const
|
|
{
|
|
return m_childNodes.First();
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the immutable last child node in this element. No
|
|
* bounds checking is performed: if this element is empty, this function
|
|
* invokes undefined behavior.
|
|
*/
|
|
const XMLNode& Last() const
|
|
{
|
|
return m_childNodes.Last();
|
|
}
|
|
|
|
/*!
|
|
* Returns an immutable iterator located at the beginning of the list of
|
|
* child nodes of this %XML element.
|
|
*/
|
|
const_iterator Begin() const
|
|
{
|
|
return m_childNodes.Begin();
|
|
}
|
|
|
|
/*!
|
|
* Returns an immutable iterator located at the end of the list of child
|
|
* nodes of this %XML element.
|
|
*/
|
|
const_iterator End() const
|
|
{
|
|
return m_childNodes.End();
|
|
}
|
|
|
|
#ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
|
|
/*!
|
|
* STL-compatible iteration. Equivalent to Begin() const.
|
|
*/
|
|
const_iterator begin() const
|
|
{
|
|
return Begin();
|
|
}
|
|
|
|
/*!
|
|
* STL-compatible iteration. Equivalent to End() const.
|
|
*/
|
|
const_iterator end() const
|
|
{
|
|
return End();
|
|
}
|
|
#endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
|
|
|
|
#ifndef __PCL_NO_MUTABLE_XML_ELEMENT_ITERATORS
|
|
|
|
/*!
|
|
* Returns a mutable iterator located at the beginning of the list of child
|
|
* nodes of this %XML element.
|
|
*/
|
|
iterator Begin()
|
|
{
|
|
return m_childNodes.Begin();
|
|
}
|
|
|
|
/*!
|
|
* Returns a mutable iterator located at the end of the list of child nodes
|
|
* of this %XML element.
|
|
*/
|
|
iterator End()
|
|
{
|
|
return m_childNodes.End();
|
|
}
|
|
|
|
/*!
|
|
* Returns an immutable iterator located at the beginning of the list of
|
|
* child nodes of this %XML element.
|
|
*/
|
|
const_iterator ConstBegin() const
|
|
{
|
|
return m_childNodes.ConstBegin();
|
|
}
|
|
|
|
/*!
|
|
* Returns an immutable iterator located at the end of the list of child
|
|
* nodes of this %XML element.
|
|
*/
|
|
const_iterator ConstEnd() const
|
|
{
|
|
return m_childNodes.ConstEnd();
|
|
}
|
|
|
|
# ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
|
|
/*!
|
|
* STL-compatible iteration. Equivalent to Begin().
|
|
*/
|
|
iterator begin()
|
|
{
|
|
return Begin();
|
|
}
|
|
|
|
/*!
|
|
* STL-compatible iteration. Equivalent to End().
|
|
*/
|
|
iterator end()
|
|
{
|
|
return End();
|
|
}
|
|
# endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
|
|
|
|
#endif // !__PCL_NO_MUTABLE_XML_ELEMENT_ITERATORS
|
|
|
|
/*!
|
|
* Returns true iff this element contains one or more child %XML elements.
|
|
*/
|
|
bool HasElements() const
|
|
{
|
|
return m_childTypes.IsFlagSet( XMLNodeType::Element );
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this element contains one or more child text blocks.
|
|
*/
|
|
bool HasText() const
|
|
{
|
|
return m_childTypes.IsFlagSet( XMLNodeType::Text );
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this element contains one or more child CDATA sections.
|
|
*/
|
|
bool HasCDATA() const
|
|
{
|
|
return m_childTypes.IsFlagSet( XMLNodeType::CDATA );
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this element contains one or more child processing
|
|
* instructions.
|
|
*/
|
|
bool HasProcessingInstructions() const
|
|
{
|
|
return m_childTypes.IsFlagSet( XMLNodeType::ProcessingInstructions );
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this element contains one or more child comment
|
|
* sections.
|
|
*/
|
|
bool HasComments() const
|
|
{
|
|
return m_childTypes.IsFlagSet( XMLNodeType::Comment );
|
|
}
|
|
|
|
/*!
|
|
* Returns the text contents of this element, or an empty string if this
|
|
* element has no text child nodes.
|
|
*
|
|
* If this element has two or more text child nodes, the returned value is
|
|
* the concatenation of all child text nodes.
|
|
*/
|
|
String Text() const;
|
|
|
|
/*!
|
|
* \internal
|
|
*/
|
|
void GetChildElements( child_element_list& list, bool recursive ) const
|
|
{
|
|
for ( const XMLNode& node : m_childNodes )
|
|
if ( node.IsElement() )
|
|
{
|
|
const XMLElement& element = static_cast<const XMLElement&>( node );
|
|
list << &element;
|
|
if ( recursive )
|
|
element.GetChildElements( list, recursive );
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* Returns a list with all child elements of this element.
|
|
*
|
|
* if \a recursive is \c true, this member function performs a recursive
|
|
* search across the entire tree structure rooted at this element. Otherwise
|
|
* only the direct descendant elements will be returned.
|
|
*/
|
|
child_element_list ChildElements( bool recursive = false ) const
|
|
{
|
|
child_element_list list;
|
|
GetChildElements( list, recursive );
|
|
return list;
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
*/
|
|
void GetChildElementsByName( child_element_list& list, const String& name, bool recursive ) const
|
|
{
|
|
for ( const XMLNode& node : m_childNodes )
|
|
if ( node.IsElement() )
|
|
{
|
|
const XMLElement& element = static_cast<const XMLElement&>( node );
|
|
if ( element.Name() == name )
|
|
{
|
|
list << &element;
|
|
if ( recursive )
|
|
element.GetChildElementsByName( list, name, recursive );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* Returns a list with all child elements of this element with the specified
|
|
* \a name.
|
|
*
|
|
* if \a recursive is \c true, this member function performs a recursive
|
|
* search across the entire tree structure rooted at this element. Otherwise
|
|
* only the direct descendant elements will be returned.
|
|
*/
|
|
child_element_list ChildElementsByName( const String& name, bool recursive = false ) const
|
|
{
|
|
child_element_list list;
|
|
GetChildElementsByName( list, name, recursive );
|
|
return list;
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
*/
|
|
void GetChildNodesByType( XMLNodeList& list, XMLNodeTypes types, bool recursive ) const
|
|
{
|
|
for ( const XMLNode& node : m_childNodes )
|
|
if ( types.IsFlagSet( node.NodeType() ) )
|
|
{
|
|
list << &node;
|
|
if ( recursive )
|
|
if ( node.IsElement() )
|
|
static_cast<const XMLElement&>( node ).GetChildNodesByType( list, types, recursive );
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* Returns a list with all child nodes of this element of the specified
|
|
* \a types. The \a types argument can be an ORed combination of XMLNodeType
|
|
* enumerated mask values.
|
|
*
|
|
* if \a recursive is \c true, this member function performs a recursive
|
|
* search across the entire tree structure rooted at this element. Otherwise
|
|
* only the direct descendant nodes will be returned.
|
|
*/
|
|
XMLNodeList ChildNodesByType( XMLNodeTypes types, bool recursive = false ) const
|
|
{
|
|
XMLNodeList list;
|
|
GetChildNodesByType( list, types, recursive );
|
|
return list;
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
*/
|
|
template <class UP>
|
|
void GetChildNodesThat( XMLNodeList& list, UP u, bool recursive ) const
|
|
{
|
|
for ( const XMLNode& node : m_childNodes )
|
|
if ( u( node ) )
|
|
{
|
|
list << &node;
|
|
if ( recursive )
|
|
if ( node.IsElement() )
|
|
static_cast<const XMLElement&>( node ).GetChildNodesThat( list, u, recursive );
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* Returns a list with all child nodes of this element that satisfy the
|
|
* specified unary predicate \a u.
|
|
*
|
|
* For each child node n in this element, n will be included in the returned
|
|
* list iff u( n ) returns true.
|
|
*
|
|
* if \a recursive is \c true, this member function performs a recursive
|
|
* search across the entire tree structure rooted at this element. Otherwise
|
|
* only the direct descendant nodes will be returned.
|
|
*/
|
|
template <class UP>
|
|
XMLNodeList ChildNodesThat( UP u, bool recursive = false ) const
|
|
{
|
|
XMLNodeList list;
|
|
GetChildNodesThat( list, u, recursive );
|
|
return list;
|
|
}
|
|
|
|
/*!
|
|
* Appends a child \a node to this %XML element.
|
|
*
|
|
* The specified \a node will be owned by this element, which will destroy
|
|
* it automatically (and recursively) upon destruction.
|
|
*/
|
|
void AddChildNode( XMLNode* node )
|
|
{
|
|
m_childNodes << node;
|
|
node->m_parent = this;
|
|
node->m_type.SetFlag( XMLNodeType::ChildNode );
|
|
m_childTypes.SetFlag( node->NodeType() );
|
|
}
|
|
|
|
/*!
|
|
* Insertion operator: Appends a child \a node to this %XML element. Returns
|
|
* a reference to this object.
|
|
*
|
|
* This operator does the same as AddChildNode( node ).
|
|
*/
|
|
XMLElement& operator <<( XMLNode* node )
|
|
{
|
|
AddChildNode( node );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* Appends an ordered sequence of child \a nodes to this %XML element.
|
|
*
|
|
* After calling this function, all existing \a nodes in the specified list
|
|
* will be owned by this element, which will destroy them automatically (and
|
|
* recursively) upon destruction.
|
|
*/
|
|
void AddChildNodes( XMLNodeList& nodes )
|
|
{
|
|
for ( XMLNode& node : nodes )
|
|
AddChildNode( &node );
|
|
}
|
|
|
|
/*!
|
|
* Insertion operator: Appends an ordered sequence of child \a nodes to this
|
|
* %XML element. Returns a reference to this object.
|
|
*
|
|
* This operator does the same as AddChildNodes( nodes ).
|
|
*/
|
|
XMLElement& operator <<( XMLNodeList& nodes )
|
|
{
|
|
AddChildNodes( nodes );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
* Appends a new child \a node to this %XML element.
|
|
*
|
|
* The specified \a node will be owned by this element, which will destroy
|
|
* it automatically (and recursively) upon destruction.
|
|
*/
|
|
void AddChildNode( XMLNode* node, const XMLNodeLocation& location )
|
|
{
|
|
node->m_location = location;
|
|
AddChildNode( node );
|
|
}
|
|
|
|
/*!
|
|
* Recursively destroys all existing child nodes in this %XML element,
|
|
* yielding an empty element.
|
|
*/
|
|
void DestroyChildNodes()
|
|
{
|
|
m_childNodes.Destroy();
|
|
m_childTypes = XMLNodeType::Undefined;
|
|
}
|
|
|
|
/*!
|
|
* Releases the child nodes of this %XML element.
|
|
*
|
|
* This function returns the (possibly empty) list of child nodes in this
|
|
* element and causes this object to forget them. The caller will be
|
|
* responsible for destroying and deallocating all of the returned nodes as
|
|
* appropriate. After calling this member function, this %XML element will
|
|
* be empty.
|
|
*/
|
|
XMLNodeList ReleaseChildNodes()
|
|
{
|
|
XMLNodeList nodes = m_childNodes;
|
|
m_childNodes.Clear();
|
|
m_childTypes = XMLNodeType::Undefined;
|
|
return nodes;
|
|
}
|
|
|
|
/*!
|
|
* Recursively serializes this %XML element and its contents. Appends the
|
|
* generated %XML source code to the specified 8-bit \a text string, encoded
|
|
* in UTF-8.
|
|
*
|
|
* See XMLNode::Serialize() for information on function parameters.
|
|
*/
|
|
void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
|
|
|
|
private:
|
|
|
|
String m_name;
|
|
XMLAttributeList m_attributes;
|
|
XMLNodeList m_childNodes;
|
|
XMLNodeTypes m_childTypes = XMLNodeType::Undefined;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class pcl::XMLElementList
|
|
* \brief Dynamic list of %XML elements
|
|
*
|
|
* %XMLElementList is a template instantiation of ReferenceArray<> for the
|
|
* XMLElement class. It is used to transport ordered sequences of child element
|
|
* nodes. See for example XMLElement::ChildElements().
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
typedef XMLElement::child_element_list XMLElementList;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLText
|
|
* \brief %XML text block
|
|
*
|
|
* This %XMLText class represents a text entity in an %XML document:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#dt-text
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLText : public XMLNode
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs a new %XMLText object.
|
|
*
|
|
* \param text The Unicode text block contents encoded as UTF-16.
|
|
*
|
|
* \param preserveSpaces If false, the text block will be transformed by
|
|
* trimming and collapsing spaces: All leading and trailing
|
|
* space characters will be removed, and all sequences of one
|
|
* or more space characters will be replaced by single white
|
|
* space characters (\#x20). If true, the specified \a text
|
|
* string will be stored intact.
|
|
*
|
|
* \param verbatim If true, the text block will be serialized unencoded,
|
|
* that is, exactly as is being specified, in the XML
|
|
* document. No codification of illegal characers such as
|
|
* quotes and '<' or '>' will be performed. This is useful to
|
|
* generate special code blocks that must be included
|
|
* literally, such as <style> or <script> tags in
|
|
* HTML and SVG documents.
|
|
*
|
|
* Besides text contents transformation, space preservation also has an
|
|
* impact in the way text blocks are serialized as %XML: New line characters
|
|
* (\#x0A) are never used to separate text blocks from their parent or
|
|
* sibling nodes when space preservation is enabled.
|
|
*/
|
|
XMLText( const String& text, bool preserveSpaces = true, bool verbatim = false )
|
|
: XMLNode( XMLNodeType::Text )
|
|
, m_text( preserveSpaces ? text : XML::CollapsedSpaces( XML::TrimmedSpaces( text ) ) )
|
|
, m_preserveSpaces( preserveSpaces )
|
|
, m_verbatim( verbatim )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLText( const XMLText& ) = default;
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) text string contained by this %XML
|
|
* text block. The returned string is encoded in UTF-16.
|
|
*/
|
|
const String& Text() const
|
|
{
|
|
return m_text;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this text block preserves space characters for
|
|
* serialization. See the class constructor for more information.
|
|
*/
|
|
bool IsPreserveSpaces() const
|
|
{
|
|
return m_preserveSpaces;
|
|
}
|
|
|
|
/*!
|
|
* Returns an encoded version of this text block. All characters that cannot
|
|
* legally occur in an %XML text block are replaced by their corresponding
|
|
* entity references.
|
|
*/
|
|
String EncodedText() const
|
|
{
|
|
return XML::EncodedText( m_text );
|
|
}
|
|
|
|
/*!
|
|
* Returns a space-transformed version of this text block.
|
|
*
|
|
* \param collapse Replace all sequences of one or more space characters
|
|
* with single white space characters (\#x20).
|
|
*
|
|
* \param trim Remove all leading and trailing space characters.
|
|
*/
|
|
String SpaceTransformedText( bool collapse, bool trim ) const
|
|
{
|
|
String text = m_text;
|
|
if ( trim )
|
|
text = XML::TrimmedSpaces( text );
|
|
if ( collapse )
|
|
text = XML::CollapsedSpaces( text );
|
|
return text;
|
|
}
|
|
|
|
/*!
|
|
* Serializes this %XML text block with UTF-8 encoding.
|
|
*
|
|
* See XMLNode::Serialize() for information on function parameters. See also
|
|
* the class constructor for information on space preservation options in
|
|
* %XML text blocks.
|
|
*/
|
|
void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
|
|
|
|
/*!
|
|
* Returns true iff a new line character (\#x0A) can be inserted before
|
|
* serializing this node after the specified \a previous node.
|
|
*
|
|
* In the case of a text block, a new line character can only be inserted
|
|
* if the block does not preserve space characters. If space preservation is
|
|
* enabled, new line characters are forbidden at the beginning and end of
|
|
* the text block serialization.
|
|
*/
|
|
bool NLAfter( const XMLNode& previous ) const override
|
|
{
|
|
return !m_preserveSpaces;
|
|
}
|
|
|
|
private:
|
|
|
|
String m_text; // N.B.: This is plain, that is, decoded, text.
|
|
bool m_preserveSpaces = true;
|
|
bool m_verbatim = false;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLCDATA
|
|
* \brief %XML CDATA section
|
|
*
|
|
* The %XMLCDATA class represents a CDATA section in an %XML document:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#sec-cdata-sect
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLCDATA : public XMLNode
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs a new %XMLCDATA object with the specified character \a data
|
|
* encoded in UTF-16.
|
|
*
|
|
* The specified \a data must not contain the sequence "]]>". Any occurrence
|
|
* of this forbidden sequence will be removed for serialization.
|
|
*/
|
|
XMLCDATA( const String& data = String() )
|
|
: XMLNode( XMLNodeType::CDATA )
|
|
, m_cdata( data )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLCDATA( const XMLCDATA& ) = default;
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) character data string, encoded as
|
|
* UTF-16, contained by this CDATA section.
|
|
*/
|
|
const String& CData() const
|
|
{
|
|
return m_cdata;
|
|
}
|
|
|
|
/*!
|
|
* Serializes this %XML CDATA section with UTF-8 encoding.
|
|
*
|
|
* See XMLNode::Serialize() for information on function parameters.
|
|
*/
|
|
void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
|
|
|
|
private:
|
|
|
|
String m_cdata;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLProcessingInstructions
|
|
* \brief %XML processing instructions
|
|
*
|
|
* The %XMLProcessingInstructions class represents a processing instructions
|
|
* (PI) tag in an %XML document:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#sec-pi
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class XMLProcessingInstructions : public XMLNode
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs a new %XMLProcessingInstructions object with the specified
|
|
* \a target name and \a instructions string, both encoded in UTF-16.
|
|
*
|
|
* The specified \a instructions string must not contain the sequence "?>".
|
|
* Any occurrence of this forbidden sequence will be removed for
|
|
* serialization.
|
|
*/
|
|
XMLProcessingInstructions( const String& target, const String& instructions )
|
|
: XMLNode( XMLNodeType::ProcessingInstructions )
|
|
, m_target( target )
|
|
, m_instructions( instructions )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLProcessingInstructions( const XMLProcessingInstructions& ) = default;
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) instructions target name.
|
|
*/
|
|
const String& Target() const
|
|
{
|
|
return m_target;
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) instructions string.
|
|
*/
|
|
const String& Instructions() const
|
|
{
|
|
return m_instructions;
|
|
}
|
|
|
|
/*!
|
|
* Serializes this %XML PI section with UTF-8 encoding.
|
|
*
|
|
* See XMLNode::Serialize() for information on function parameters.
|
|
*/
|
|
void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
|
|
|
|
private:
|
|
|
|
String m_target;
|
|
String m_instructions;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLComment
|
|
* \brief %XML comment section
|
|
*
|
|
* The %XMLComment class represents a comment in an %XML document:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#sec-comments
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLComment : public XMLNode
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs a new %XMLComment object with the specified \a comment string
|
|
* encoded in UTF-16.
|
|
*
|
|
* The specified \a comment must not contain the sequence "--" or end with
|
|
* a '-' character. Any occurrence of these forbidden sequences will be
|
|
* removed for serialization.
|
|
*/
|
|
XMLComment( const String& comment )
|
|
: XMLNode( XMLNodeType::Comment )
|
|
, m_comment( comment )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLComment( const XMLComment& ) = default;
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) comment string.
|
|
*/
|
|
const String& Comment() const
|
|
{
|
|
return m_comment;
|
|
}
|
|
|
|
/*!
|
|
* Serializes this %XML comment section with UTF-8 encoding.
|
|
*
|
|
* See XMLNode::Serialize() for information on function parameters.
|
|
*/
|
|
void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
|
|
|
|
private:
|
|
|
|
String m_comment;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLUnknownElement
|
|
* \brief Unsupported or invalid %XML element
|
|
*
|
|
* %XMLUnknownElement represents an invalid or unrecognized %XML element
|
|
* retrieved while parsing an %XML document. In the current PCL implementation,
|
|
* an %XMLUnknownElement object is generated if the parser finds an element
|
|
* whose start-tag begins with the "<!" token and is neither a comment section
|
|
* nor a DOCTYPE declaration.
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLUnknownElement : public XMLNode
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs an %XMLUnknownElement with the specified qualified \a name and
|
|
* element \a parameters.
|
|
*/
|
|
XMLUnknownElement( const String& name, const String& parameters = String() )
|
|
: XMLNode( XMLNodeType::Unknown )
|
|
, m_name( name )
|
|
, m_parameters( parameters )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLUnknownElement( const XMLUnknownElement& ) = default;
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) unknown element name.
|
|
*/
|
|
const String& Name() const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) unknown element parameters.
|
|
*/
|
|
const String& Parameters() const
|
|
{
|
|
return m_parameters;
|
|
}
|
|
|
|
/*!
|
|
* Serializes this %XML unknown element with UTF-8 encoding.
|
|
*
|
|
* See XMLNode::Serialize() for information on function parameters.
|
|
*/
|
|
void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
|
|
|
|
private:
|
|
|
|
String m_name;
|
|
String m_parameters;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLDeclaration
|
|
* \brief %XML declaration
|
|
*
|
|
* %XMLDeclaration represents an %XML declaration in an %XML document prolog:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#sec-prolog-dtd
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLDeclaration : public XMLComponent
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs a new %XMLDeclaration object with the specified \a version,
|
|
* optional \a encoding and \a standalone document specification.
|
|
*/
|
|
XMLDeclaration( const String& version = String(), const String& encoding = String(), bool standalone = false )
|
|
: m_version( version )
|
|
, m_encoding( encoding )
|
|
, m_standalone( standalone )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLDeclaration( const XMLDeclaration& ) = default;
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) %XML version string.
|
|
*/
|
|
const String& Version() const
|
|
{
|
|
return m_version;
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) document encoding string.
|
|
*/
|
|
const String& DocumentEncoding() const
|
|
{
|
|
return m_encoding;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this %XML declaration specifies a standalone document.
|
|
*/
|
|
bool IsStandaloneDocument() const
|
|
{
|
|
return m_standalone;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this %XML declaration has been defined. This function
|
|
* can be used to check if a parsed %XML document includes an %XML
|
|
* declaration.
|
|
*/
|
|
bool IsDefined() const
|
|
{
|
|
return !m_version.IsEmpty();
|
|
}
|
|
|
|
/*!
|
|
* Serializes this %XML declaration.
|
|
*
|
|
* The generated serialization will be appended to the specified 8-bit
|
|
* \a text string. If no version string has been defined for this object, a
|
|
* 'version="1.0"' attribute will be generated. Similarly, if no encoding
|
|
* string has been defined, an 'encoding="UTF-8"' attribute will be
|
|
* generated.
|
|
*/
|
|
void Serialize( IsoString& text ) const;
|
|
|
|
private:
|
|
|
|
String m_version;
|
|
String m_encoding;
|
|
bool m_standalone = false;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLDocTypeDeclaration
|
|
* \brief %XML DOCTYPE declaration
|
|
*
|
|
* %XMLDocTypeDeclaration represents a document type declaration in an %XML
|
|
* document prolog:
|
|
*
|
|
* https://www.w3.org/TR/xml11/#dt-doctype
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLDocTypeDeclaration : public XMLComponent
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs a new %XMLDocTypeDeclaration object with the specified
|
|
* document type \a name and type \a definition.
|
|
*/
|
|
XMLDocTypeDeclaration( const String& name = String(), const String& definition = String() )
|
|
: m_name( name )
|
|
, m_definition( definition )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
XMLDocTypeDeclaration( const XMLDocTypeDeclaration& ) = default;
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) document type name.
|
|
*/
|
|
const String& Name() const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) document type definition.
|
|
*/
|
|
const String& Definition() const
|
|
{
|
|
return m_definition;
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this document type declaration has been defined. This
|
|
* function can be used to check if a parsed %XML document includes an
|
|
* DOCTYPE declaration.
|
|
*/
|
|
bool IsDefined() const
|
|
{
|
|
return !m_name.IsEmpty();
|
|
}
|
|
|
|
/*!
|
|
* Serializes this DOCTYPE declaration with UTF-8 encoding.
|
|
*
|
|
* The generated serialization will be appended to the specified 8-bit
|
|
* \a text string, encoded in UTF-8. This function won't generate any
|
|
* characters if no document type name has been defined for this object.
|
|
*/
|
|
void Serialize( IsoString& text ) const;
|
|
|
|
private:
|
|
|
|
String m_name;
|
|
String m_definition;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLElementFilter
|
|
* \brief A functional class for filtering %XML elements
|
|
*
|
|
* Element filters can be used with XMLDocument objects to reject elements
|
|
* selectively while parsing an %XML document.
|
|
*
|
|
* When an element filter has been defined, %XMLDocument calls its
|
|
* reimplemented operator()( const XMLElement*, const String& ) member function
|
|
* when an element's start-tag is found, passing its parent element and name to
|
|
* the function. If the function returns false, the element is rejected,
|
|
* including all of its child nodes, and the parsing process continues after
|
|
* the corresponding end-tag.
|
|
*
|
|
* If the first function call described above returns true, %XMLDocument calls
|
|
* operator()( const XMLElement*, const String&, const XMLAttributeList& ) with
|
|
* the parent, name and attributes of the element. Again, if the function
|
|
* returns false the element is skipped completely until its end-tag is found.
|
|
* If the function returns true, the element is accepted, added to the DOM
|
|
* being generated, and parsed.
|
|
*
|
|
* Element filters can be useful to accelerate %XML document parsing and reduce
|
|
* its memory consumption considerably, when only a subset of possible elements
|
|
* is required.
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
struct XMLElementFilter
|
|
{
|
|
/*!
|
|
* Virtual destructor.
|
|
*/
|
|
virtual ~XMLElementFilter()
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Returns true if an %XML element with the specified \a name and \a parent
|
|
* element is acceptable; false if the element must be ignored.
|
|
*/
|
|
virtual bool operator()( const XMLElement* parent, const String& name ) const = 0;
|
|
|
|
/*!
|
|
* Returns true if an %XML element with the specified \a name, \a attributes
|
|
* and \a parent element is acceptable; false if the element must be
|
|
* ignored. This function is only called after a previous call to
|
|
* operator()( const XMLElement*, const String& ) has returned true for the
|
|
* same element.
|
|
*
|
|
* The default implementation returns true, which facilitates
|
|
* implementations where elements are only filtered by their names.
|
|
*/
|
|
virtual bool operator()( const XMLElement* parent, const String& name, const XMLAttributeList& attributes ) const
|
|
{
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \namespace pcl::XMLParserOption
|
|
* \brief %XML document parsing options
|
|
*
|
|
* <table border="1" cellpadding="4" cellspacing="0">
|
|
* <tr><td>XMLParserOption::IgnoreComments</td> <td>Do not add comment nodes to the DOM.</td></tr>
|
|
* <tr><td>XMLParserOption::IgnoreUnknownElements</td> <td>Do not add unknown/invalid elements to the DOM.</td></tr>
|
|
* <tr><td>XMLParserOption::IgnoreStrayCharacters</td> <td>Be tolerant of non-space characters outside markup.</td></tr>
|
|
* <tr><td>XMLParserOption::NormalizeTextSpaces</td> <td>Trim and collapse spaces in all child text nodes.</td></tr>
|
|
* </table>
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
namespace XMLParserOption
|
|
{
|
|
enum mask_type
|
|
{
|
|
IgnoreComments = 0x00000001,
|
|
IgnoreUnknownElements = 0x00000002,
|
|
IgnoreStrayCharacters = 0x00000004,
|
|
NormalizeTextSpaces = 0x00000008
|
|
};
|
|
}
|
|
|
|
/*!
|
|
* \class pcl::XMLParserOptions
|
|
* \brief A collection of %XML document parsing options
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
typedef Flags<XMLParserOption::mask_type> XMLParserOptions;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class XMLDocument
|
|
* \brief %XML document parsing and generation
|
|
*
|
|
* %XMLDocument implements parsing and generation of well-formed %XML
|
|
* documents.
|
|
*
|
|
* The Parse() member function reads and interprets a Unicode text string to
|
|
* generate a read-only document object model (DOM) that represents the data
|
|
* entities defined by a well-formed %XML document. The DOM can be inspected
|
|
* with several member functions of the %XMLDocument class. All %XML nodes and
|
|
* elements in a document can be visited recursively with specialized accessor
|
|
* functions and iterators. See the Begin() and End() functions (and their
|
|
* STL-compatible equivalents, begin() and end()), as well as XML(), DocType(),
|
|
* RootElement(), and operator []( int ), among others.
|
|
*
|
|
* For generation of %XML documents, the Serialize() member function builds a
|
|
* new document as a Unicode string encoded in UTF-8. The document's root node
|
|
* and several nodes and critical components must be defined before document
|
|
* generation - see the SetXML(), SetDocType(), AddNode() and SetRootElement()
|
|
* member functions.
|
|
*
|
|
* For general information on %XML, the authoritative sources are the W3C
|
|
* recommendations:
|
|
*
|
|
* https://www.w3.org/TR/xml/
|
|
* https://www.w3.org/TR/xml11/
|
|
* https://www.w3.org/TR/xml-names/
|
|
*
|
|
* The following example shows how an existing document can be parsed as a new
|
|
* %XMLDocument object, and then a new %XML document can be generated and
|
|
* written to a disk file, all in just three source code lines:
|
|
*
|
|
* \code
|
|
* XMLDocument xml;
|
|
* xml.Parse( File::ReadTextFile( "/path/to/file.xml" ).UTF8ToUTF16() );
|
|
* File::WriteTextFile( "/tmp/test.xml", xml.Serialize() );
|
|
* \endcode
|
|
*
|
|
* In this case the new document is generated without superfluous space
|
|
* characters. To enable automatic indentation of text lines, see the
|
|
* EnableAutoFormatting(), SetIndentSize() and EnableIndentTabs() member
|
|
* functions.
|
|
*
|
|
* The following example:
|
|
*
|
|
* \code
|
|
* XMLElement* e1 = new XMLElement( "Foo", XMLAttributeList() << XMLAttribute( "version", "1.0" ) );
|
|
*
|
|
* XMLElement* e2 = new XMLElement( "Bar" );
|
|
* *e2 << new XMLElement( "bar_child_1" )
|
|
* << new XMLElement( "bar_child_2" );
|
|
*
|
|
* XMLElement* e3 = new XMLElement( "FooBar" );
|
|
* *e3 << new XMLText( "This is FooBar." );
|
|
*
|
|
* *e1 << e2 << e3;
|
|
*
|
|
* XMLDocument xml;
|
|
* xml.SetXML( "1.0" );
|
|
* xml.SetRootElement( e1 );
|
|
* xml.EnableAutoFormatting();
|
|
* xml.SerializeToFile( "/tmp/foobar.xml" );
|
|
* \endcode
|
|
*
|
|
* generates this %XML file in /tmp/foobar.xml:
|
|
*
|
|
* \code
|
|
* <?xml version="1.0" encoding="UTF-8"?>
|
|
* <Foo version="1.0">
|
|
* <Bar>
|
|
* <bar_child_1/>
|
|
* <bar_child_2/>
|
|
* </Bar>
|
|
* <FooBar>This is FooBar.</FooBar>
|
|
* </Foo>
|
|
* \endcode
|
|
*
|
|
* \ingroup xml_parsing_and_generation
|
|
*/
|
|
class PCL_CLASS XMLDocument
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Represents a mutable child node list iterator.
|
|
*/
|
|
typedef XMLNodeList::iterator iterator;
|
|
|
|
/*!
|
|
* Represents an immutable child node list iterator.
|
|
*/
|
|
typedef XMLNodeList::const_iterator const_iterator;
|
|
|
|
/*!
|
|
* Represents an option to control the %XML parser behavior. Valid options
|
|
* are defined in the XMLParserOption namespace.
|
|
*/
|
|
typedef XMLParserOption::mask_type parser_option;
|
|
|
|
/*!
|
|
* Default constructor. Constructs an empty %XML document.
|
|
*
|
|
* For serialization of XML documents, this constructor defines the
|
|
* following default settings:
|
|
*
|
|
* \li Auto-formatting disabled.
|
|
* \li Use space characters (\#x20) for indentation.
|
|
* \li Indentation size = 3 spaces.
|
|
*/
|
|
XMLDocument() = default;
|
|
|
|
/*!
|
|
* Virtual destructor. Recursively destroys all %XML elements, declarations
|
|
* and auxiliary data associated with this object.
|
|
*/
|
|
virtual ~XMLDocument()
|
|
{
|
|
m_nodes.Destroy();
|
|
m_root = nullptr;
|
|
RemoveElementFilter();
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor. This constructor is disabled because %XMLDocument
|
|
* represents unique objects.
|
|
*/
|
|
XMLDocument( const XMLDocument& ) = delete;
|
|
|
|
/*!
|
|
* Copy assignment. This operator is disabled because %XMLDocument
|
|
* represents unique objects.
|
|
*/
|
|
XMLDocument& operator =( const XMLDocument& ) = delete;
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) %XML declaration object associated
|
|
* with this document.
|
|
*/
|
|
const XMLDeclaration& XML() const
|
|
{
|
|
return m_xml;
|
|
}
|
|
|
|
/*!
|
|
* Defines an %XML declaration in this %XML document.
|
|
*/
|
|
void SetXML( const XMLDeclaration& xml )
|
|
{
|
|
m_xml = xml;
|
|
}
|
|
|
|
/*!
|
|
* Defines an %XML declaration in this %XML document with the specified
|
|
* \a version, \a encoding and \a standalone attributes.
|
|
*/
|
|
void SetXML( const String& version = "1.0", const String& encoding = "UTF-8", bool standalone = false )
|
|
{
|
|
SetXML( XMLDeclaration( version, encoding, standalone ) );
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) %XML document type declaration
|
|
* object associated with this document.
|
|
*/
|
|
const XMLDocTypeDeclaration& DocType() const
|
|
{
|
|
return m_docType;
|
|
}
|
|
|
|
/*!
|
|
* Associates a new %XML document type declaration object with this %XML
|
|
* document.
|
|
*/
|
|
void SetDocType( const XMLDocTypeDeclaration& docType )
|
|
{
|
|
m_docType = docType;
|
|
}
|
|
|
|
/*!
|
|
* Returns a pointer to the (immutable) root element of this %XML document.
|
|
* If there is no root element, for example when this is an uninitialized
|
|
* %XMLDocument instance, this function returns \c nullptr.
|
|
*
|
|
* \sa ReleaseRootElement(), SetRootElement()
|
|
*/
|
|
const XMLElement* RootElement() const
|
|
{
|
|
return m_root;
|
|
}
|
|
|
|
/*!
|
|
* Releases the root element of this %XML document.
|
|
*
|
|
* This function returns the root element and causes this object to forget
|
|
* it. The caller will be responsible for destroying and deallocating the
|
|
* returned XMLElement instance as appropriate. This function performs an
|
|
* implicit call to Clear(), so the document will be empty after calling it.
|
|
*
|
|
* If there is no root element, for example when this is an uninitialized
|
|
* %XMLDocument instance, this function returns \c nullptr.
|
|
*
|
|
* \sa RootElement(), SetRootElement()
|
|
*/
|
|
XMLElement* ReleaseRootElement()
|
|
{
|
|
XMLElement* root = m_root;
|
|
m_nodes.RemovePointer( m_root );
|
|
Clear();
|
|
return root;
|
|
}
|
|
|
|
/*!
|
|
* Returns the number of nodes in this %XML document, or zero if this is an
|
|
* empty or uninitialized %XMLDocument object.
|
|
*/
|
|
int NodeCount() const
|
|
{
|
|
return int( m_nodes.Length() );
|
|
}
|
|
|
|
/*!
|
|
* Returns true iff this is an empty %XML document. An empty document has no
|
|
* %XML nodes.
|
|
*/
|
|
bool IsEmpty() const
|
|
{
|
|
return m_nodes.IsEmpty();
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) document node at the specified
|
|
* zero-based index \a i. No bounds checking is performed: if the specified
|
|
* index is invalid, this function invokes undefined behavior.
|
|
*/
|
|
const XMLNode& operator []( int i ) const
|
|
{
|
|
return m_nodes[i];
|
|
}
|
|
|
|
/*!
|
|
* Returns an immutable iterator located at the beginning of the list of
|
|
* nodes of this %XML document.
|
|
*/
|
|
const_iterator Begin() const
|
|
{
|
|
return m_nodes.Begin();
|
|
}
|
|
|
|
/*!
|
|
* Returns an immutable iterator located at the end of the list of
|
|
* nodes of this %XML document.
|
|
*/
|
|
const_iterator End() const
|
|
{
|
|
return m_nodes.End();
|
|
}
|
|
|
|
#ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
|
|
/*!
|
|
* STL-compatible iteration. Equivalent to Begin() const.
|
|
*/
|
|
const_iterator begin() const
|
|
{
|
|
return Begin();
|
|
}
|
|
|
|
/*!
|
|
* STL-compatible iteration. Equivalent to End() const.
|
|
*/
|
|
const_iterator end() const
|
|
{
|
|
return End();
|
|
}
|
|
#endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
|
|
|
|
/*!
|
|
* Appends a new top-level %XML node to this document.
|
|
*
|
|
* If the specified \a node already belongs to an %XMLDocument object, or if
|
|
* a null pointer is specified, this member function will throw an Error
|
|
* exception.
|
|
*
|
|
* The specified \a node will be appended to the current list of document
|
|
* nodes. If there is a root element in this document, the new \a node will
|
|
* be appended after the root element.
|
|
*
|
|
* The \a node will be owned by this document object, which will destroy and
|
|
* deallocate it automatically when appropriate.
|
|
*/
|
|
void AddNode( XMLNode* node );
|
|
|
|
/*!
|
|
* Insertion operator. Returns a reference to this %XMLDocument object.
|
|
*
|
|
* This operator is equivalent to AddNode( XMLNode* ).
|
|
*/
|
|
XMLDocument& operator <<( XMLNode* node )
|
|
{
|
|
AddNode( node );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* Sets the root element of this %XML document.
|
|
*
|
|
* If the specified \a element already belongs to an %XMLDocument object, if
|
|
* a null pointer is specified, or if a root node has already been defined
|
|
* for this document, this member function will throw an Error exception.
|
|
*
|
|
* The specified \a element will be appended to the current list of document
|
|
* nodes. The \a element will be owned by this document object, which will
|
|
* destroy and deallocate it automatically when appropriate.
|
|
*
|
|
* \sa RootElement(), ReleaseRootElement()
|
|
*/
|
|
void SetRootElement( XMLElement* element );
|
|
|
|
/*!
|
|
* Destroys and deallocates all nodes and elements in this %XML document
|
|
* object, and initializes all internal structures to a default state,
|
|
* yielding an uninitialized object.
|
|
*
|
|
* If there is an element filter or a set of parser options defined for this
|
|
* object, they are preserved by this function. See RemoveElementFilter() to
|
|
* remove a filter set by a previous call to SetElementFilter(). See also
|
|
* ClearParserOptions() to reset parser options set by previous calls to
|
|
* SetParserOption().
|
|
*/
|
|
void Clear();
|
|
|
|
/*!
|
|
* Sets a new element filter for this object. The specified object will be
|
|
* owned by this %XMLDocument instance, which will destroy and deallocate it
|
|
* when appropriate.
|
|
*
|
|
* See XMLElementFilter for a complete description of the element filtering
|
|
* functionality. See RemoveElementFilter() to remove the element filter
|
|
* set by this function.
|
|
*/
|
|
void SetElementFilter( XMLElementFilter* filter )
|
|
{
|
|
delete m_filter, m_filter = filter;
|
|
}
|
|
|
|
/*!
|
|
* Removes an element filter set by a previous call to SetElementFilter().
|
|
* If no filter has been defined for this object, this function has no
|
|
* effect.
|
|
*/
|
|
void RemoveElementFilter()
|
|
{
|
|
SetElementFilter( nullptr );
|
|
}
|
|
|
|
/*!
|
|
* Enables or disables an %XML document parser option for this object. Valid
|
|
* options are defined in the XMLParserOption namespace. See
|
|
* ClearParserOptions() to reset all parser options to a default state.
|
|
*/
|
|
void SetParserOption( parser_option option, bool on = true )
|
|
{
|
|
m_parserOptions.SetFlag( option, on );
|
|
}
|
|
|
|
/*!
|
|
* Sets the specified parser \a options. Valid options are defined in the
|
|
* XMLParserOption namespace. See ClearParserOptions() to reset all parser
|
|
* options to a default state.
|
|
*/
|
|
void SetParserOptions( XMLParserOptions options )
|
|
{
|
|
m_parserOptions = options;
|
|
}
|
|
|
|
/*!
|
|
* Resets all parser options defined for this object by a previous call to
|
|
* SetParserOption() or SetParserOptions().
|
|
*/
|
|
void ClearParserOptions()
|
|
{
|
|
m_parserOptions.Clear();
|
|
}
|
|
|
|
/*!
|
|
* %XML document parser. Reads and interprets the specified Unicode \a text
|
|
* string, which must be encoded in UTF-16, as a well-formed %XML document.
|
|
*
|
|
* This member function generates a document object model (DOM) to represent
|
|
* the data entities defined by the source %XML document. The DOM can then
|
|
* be inspected with several member functions of the %XMLDocument class. All
|
|
* %XML nodes and elements can be visited recursively with specialized
|
|
* iterators. See the Begin() and End() functions (and their STL-compatible
|
|
* equivalents, begin() and end()), as well as XML(), DocType(),
|
|
* RootElement() and operator []( int ), among others.
|
|
*/
|
|
void Parse( const String& text );
|
|
|
|
/*!
|
|
* Returns true iff the auto-formatting feature is enabled for %XML
|
|
* serialization with this %XMLDocument object.
|
|
*
|
|
* When auto-formatting is enabled, ignorable line breaks (\#x0A) and white
|
|
* space characters (either spaces (\#x20) or tabulators (\#x09)) are used
|
|
* to separate %XML nodes and to indent text lines, respectively, improving
|
|
* readability of generated %XML code. When auto-formatting is disabled, no
|
|
* superfluous white space characters are generated. The only exception is
|
|
* XMLText child nodes with space preservation enabled, which always ignore
|
|
* all indentation and formatting settings in order to reproduce their text
|
|
* contents without modification.
|
|
*
|
|
* The auto-formatting feature is always disabled by default for newly
|
|
* constructed %XMLDocument objects. This is because the main purpose and
|
|
* utility of %XMLDocument is parsing and generation of %XML documents
|
|
* intended for automated data management, without direct user intervention.
|
|
* Auto-formatting is only useful for human readability of %XML source code.
|
|
*/
|
|
bool IsAutoFormatting() const
|
|
{
|
|
return m_autoFormatting;
|
|
}
|
|
|
|
/*!
|
|
* Enables the auto-formatting feature for generation of %XML code. See
|
|
* IsAutoFormatting() for more information.
|
|
*/
|
|
void EnableAutoFormatting( bool enable = true )
|
|
{
|
|
m_autoFormatting = enable;
|
|
}
|
|
|
|
/*!
|
|
* Disables the auto-formatting feature for generation of %XML code. See
|
|
* IsAutoFormatting() for more information.
|
|
*/
|
|
void DisableAutoFormatting( bool disable = true )
|
|
{
|
|
EnableAutoFormatting( !disable );
|
|
}
|
|
|
|
/*!
|
|
* Returns the number of space characters (\#x20) used for each indentation
|
|
* level of text lines, when the auto-formatting feature is enabled and
|
|
* space characters are used for indentation.
|
|
*
|
|
* When tabulator characters (\#x09) are used for indentation, this setting
|
|
* is ignored and a single tabulator is always used for each indentation
|
|
* level. See IsAutoFormatting() and SetIndentSize() for more information.
|
|
*/
|
|
int IndentSize() const
|
|
{
|
|
return m_indentSize;
|
|
}
|
|
|
|
/*!
|
|
* Sets the number of indentation space characters.
|
|
*
|
|
* \param indentSize Number of space characters (\#x20) used for a level
|
|
* of indentation of text lines in generated %XML code,
|
|
* when the auto-formatting feature is enabled and
|
|
* space characters are used for indentation. The valid
|
|
* range of values is from zero (for no indentation) to
|
|
* 8 characters.
|
|
*
|
|
* When the indentation size is zero and auto-formatting is enabled, each
|
|
* document node is generated in a separate line without any indentation.
|
|
* XMLText child nodes with space preservation enabled will always ignore
|
|
* all indentation and formatting settings, in order to reproduce their text
|
|
* contents without modification.
|
|
*
|
|
* When tabulator characters (\#x09) are used for indentation, this setting
|
|
* is ignored and a single tabulator character is always used for each
|
|
* indentation level.
|
|
*
|
|
* The default indentation size is 3 for newly constructed %XMLDocument
|
|
* objects.
|
|
*/
|
|
void SetIndentSize( int indentSize )
|
|
{
|
|
m_indentSize = Range( indentSize, 0, 8 );
|
|
}
|
|
|
|
/*!
|
|
* Returns true if tabulator characters (\#x09) are used for indentation of
|
|
* text lines, when the auto-formatting feature is enabled. Returns false if
|
|
* space characters (\#x20) are used for indentation.
|
|
*
|
|
* By default, text indentation is always performed using space characters
|
|
* by newly constructed %XMLDocument objects.
|
|
*/
|
|
bool IsIndentTabs() const
|
|
{
|
|
return m_indentTabs;
|
|
}
|
|
|
|
/*!
|
|
* Enables the use of tabulator characters (\#x09) for indentation. See
|
|
* IsIndentTabs() for more information.
|
|
*/
|
|
void EnableIndentTabs( bool enable = true )
|
|
{
|
|
m_indentTabs = enable;
|
|
}
|
|
|
|
/*!
|
|
* Disables the use of tabulator characters (\#x09) for indentation. See
|
|
* IsIndentTabs() for more information.
|
|
*/
|
|
void DisableIndentTabs( bool disable = true )
|
|
{
|
|
EnableIndentTabs( !disable );
|
|
}
|
|
|
|
/*!
|
|
* Serializes this %XML document. Returns the generated serialization as a
|
|
* Unicode string encoded in UTF-8.
|
|
*
|
|
* To serialize a well-formed %XML document, this object must be initialized
|
|
* first by defining a root element (see SetRootElement()) and other
|
|
* document nodes, as necessary (see SetXML(), SetDocType(), and AddNode()).
|
|
*
|
|
* For formatting and indentation settings, see IsAutoFormatting(),
|
|
* IndentSize() and IsIndentTabs().
|
|
*/
|
|
IsoString Serialize() const;
|
|
|
|
/*!
|
|
* Serializes this %XML document and writes the result to a file at the
|
|
* specified \a path with UTF-8 encoding.
|
|
*
|
|
* See Serialize() for more information.
|
|
*
|
|
* \warning If a file already exists at the specified path, its previous
|
|
* contents will be lost after calling this function.
|
|
*/
|
|
void SerializeToFile( const String& path ) const;
|
|
|
|
private:
|
|
|
|
XMLDeclaration m_xml;
|
|
XMLDocTypeDeclaration m_docType;
|
|
XMLNodeList m_nodes;
|
|
XMLElement* m_root = nullptr;
|
|
XMLElementFilter* m_filter = nullptr;
|
|
XMLParserOptions m_parserOptions;
|
|
XMLNodeLocation m_location;
|
|
bool m_autoFormatting = false;
|
|
bool m_indentTabs = false;
|
|
int m_indentSize = 3;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
} // pcl
|
|
|
|
#endif // __PCL_XML_h
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// EOF pcl/XML.h - Released 2022-03-12T18:59:29Z
|