PCL
XML.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.4.0
6 // ----------------------------------------------------------------------------
7 // pcl/XML.h - Released 2020-08-25T19:17:02Z
8 // ----------------------------------------------------------------------------
9 // This file is part of the PixInsight Class Library (PCL).
10 // PCL is a multiplatform C++ framework for development of PixInsight modules.
11 //
12 // Copyright (c) 2003-2020 Pleiades Astrophoto S.L. All Rights Reserved.
13 //
14 // Redistribution and use in both source and binary forms, with or without
15 // modification, is permitted provided that the following conditions are met:
16 //
17 // 1. All redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer.
19 //
20 // 2. All redistributions in binary form must reproduce the above copyright
21 // notice, this list of conditions and the following disclaimer in the
22 // documentation and/or other materials provided with the distribution.
23 //
24 // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
25 // of their contributors, may be used to endorse or promote products derived
26 // from this software without specific prior written permission. For written
27 // permission, please contact info@pixinsight.com.
28 //
29 // 4. All products derived from this software, in any form whatsoever, must
30 // reproduce the following acknowledgment in the end-user documentation
31 // and/or other materials provided with the product:
32 //
33 // "This product is based on software from the PixInsight project, developed
34 // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
35 //
36 // Alternatively, if that is where third-party acknowledgments normally
37 // appear, this acknowledgment must be reproduced in the product itself.
38 //
39 // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
40 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
43 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
45 // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
46 // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 // POSSIBILITY OF SUCH DAMAGE.
50 // ----------------------------------------------------------------------------
51 
52 #ifndef __PCL_XML_h
53 #define __PCL_XML_h
54 
56 
57 #include <pcl/Defs.h>
58 
59 #include <pcl/Exception.h>
60 #include <pcl/ReferenceArray.h>
61 #include <pcl/String.h>
62 
63 namespace pcl
64 {
65 
66 // ----------------------------------------------------------------------------
67 
72 // ----------------------------------------------------------------------------
73 
74 class PCL_CLASS XMLDocument;
75 class PCL_CLASS XMLElement;
76 
77 // ----------------------------------------------------------------------------
78 
84 class PCL_CLASS XML
85 {
86 public:
87 
92  XML() = delete;
93 
98  XML( const XML& ) = delete;
99 
104  XML& operator =( const XML& ) = delete;
105 
110  ~XML() = delete;
111 
116  template <typename T>
117  static bool IsWhiteSpaceChar( T c )
118  {
119  return c == 0x20 || c == 9;
120  }
121 
126  template <typename T>
127  static bool IsLineBreakChar( T c )
128  {
129  return c == 0x0A || c == 0x0D;
130  }
131 
137  template <typename T>
138  static bool IsSpaceChar( T c )
139  {
140  return IsWhiteSpaceChar( c ) || IsLineBreakChar( c );
141  }
142 
148  template <typename T>
149  static bool IsNameStartChar( T c )
150  {
151  return c >= T( 'a' ) && c <= T( 'z' )
152  || c >= T( 'A' ) && c <= T( 'Z' )
153  || c == T( '_' )
154  || c == T( ':' )
155  || c >= 0xC0 && c <= 0xD6
156  || c >= 0xD8 && c <= 0xF6
157  || c >= 0xF8 && c <= 0x2FF
158  || c >= 0x370 && c <= 0x37D
159  || c >= 0x37F && c <= 0x1FFF
160  || c >= 0x200C && c <= 0x200D
161  || c >= 0x2070 && c <= 0x218F
162  || c >= 0x2C00 && c <= 0x2FEF
163  || c >= 0x3001 && c <= 0xD7FF
164  || c >= 0xF900 && c <= 0xFDCF
165  || c >= 0xFDF0 && c <= 0xFFFD
166  || uint32( c ) >= 0x10000 && uint32( c ) <= 0xEFFFF;
167  }
168 
174  template <typename T>
175  static bool IsNameChar( T c )
176  {
177  return IsNameStartChar( c )
178  || c >= T( '0' ) && c <= T( '9' )
179  || c == T( '-' )
180  || c == T( '.' )
181  || c == 0xB7
182  || c >= 0x0300 && c <= 0x036F
183  || c >= 0x203F && c <= 0x2040;
184  }
185 
191  template <typename T>
192  static bool IsRestrictedChar( T c )
193  {
194  return c >= 0x00 && c <= 0x08
195  || c >= 0x0B && c <= 0x0C
196  || c >= 0x0E && c <= 0x1F
197  || c >= 0x7F && c <= 0x84
198  || c >= 0x86 && c <= 0x9F;
199  }
200 
207  static bool IsValidName( const String& name )
208  {
209  if ( !name.IsEmpty() )
210  if ( IsNameStartChar( *name ) )
211  for ( String::const_iterator i = name.Begin(); ; )
212  {
213  if ( ++i == name.End() )
214  return true;
215  if ( !IsNameChar( *i ) )
216  break;
217  }
218  return false;
219  }
220 
225  static String TrimmedSpaces( String::const_iterator i, String::const_iterator j );
226 
231  static String TrimmedSpaces( const String& text );
232 
238  static String CollapsedSpaces( String::const_iterator i, String::const_iterator j );
239 
244  static String CollapsedSpaces( const String& text );
245 
261  static String DecodedText( String::const_iterator i, String::const_iterator j );
262 
270  static String DecodedText( const String& text );
271 
279  {
280  return EncodedText( String( i, j ), apos );
281  }
282 
289  static String EncodedText( const String& text, bool apos = true );
290 
307  static String ReferenceValue( String::const_iterator i, String::const_iterator j );
308 
316  static String ReferenceValue( const String& reference )
317  {
318  return ReferenceValue( reference.Begin(), reference.End() );
319  }
320 };
321 
322 // ----------------------------------------------------------------------------
323 
334 class PCL_CLASS XMLComponent
335 {
336 public:
337 
342  XMLComponent() = default;
343 
347  XMLComponent( const XMLComponent& ) = default;
348 
354  {
355  return m_parent;
356  }
357 
362  bool IsTopLevel() const
363  {
364  return m_parent == nullptr;
365  }
366 
367 private:
368 
369  XMLElement* m_parent = nullptr;
370 
371  friend class XMLElement;
372 };
373 
374 // ----------------------------------------------------------------------------
375 
394 namespace XMLNodeType
395 {
396  enum mask_type
397  {
398  Undefined = 0x00000000,
399  ChildNode = 0x80000000,
400  Unknown = 0x10000000,
401  Element = 0x00000001,
402  Text = 0x00000002,
403  CDATA = 0x00000004,
404  ProcessingInstructions = 0x00000008,
405  Comment = 0x00000010
406  };
407 
412  String AsString( mask_type type );
413 }
414 
421 
422 // ----------------------------------------------------------------------------
423 
430 {
435  int64 line = 0;
436 
448  int64 column = 0;
449 
454  XMLNodeLocation() = default;
455 
460  XMLNodeLocation( int line_, int column_ )
461  : line( line_ )
462  , column( column_ )
463  {
464  }
465 
469  XMLNodeLocation( const XMLNodeLocation& ) = default;
470 
483  String ToString() const;
484 };
485 
486 // ----------------------------------------------------------------------------
487 
499 class PCL_CLASS XMLNode : public XMLComponent
500 {
501 public:
502 
507  typedef XMLNodeType::mask_type node_type;
508 
514  XMLNode( node_type type )
515  : m_type( type )
516  {
517  }
518 
526  XMLNode( const XMLNode& x )
527  : m_type( x.NodeType() )
528  , m_location( x.m_location )
529  {
530  }
531 
535  virtual ~XMLNode()
536  {
537  }
538 
542  bool IsChildNode() const
543  {
544  return m_type.IsFlagSet( XMLNodeType::ChildNode );
545  }
546 
550  node_type NodeType() const
551  {
552  return static_cast<node_type>( XMLNodeTypes::flag_type( m_type & unsigned( ~XMLNodeType::ChildNode ) ) );
553  }
554 
559  bool IsElement() const
560  {
561  return NodeType() == XMLNodeType::Element;
562  }
563 
568  bool IsText() const
569  {
570  return NodeType() == XMLNodeType::Text;
571  }
572 
577  bool IsComment() const
578  {
579  return NodeType() == XMLNodeType::Comment;
580  }
581 
585  const XMLNodeLocation& Location() const
586  {
587  return m_location;
588  }
589 
615  virtual void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const = 0;
616 
621  virtual bool NLAfter( const XMLNode& previous ) const;
622 
623 private:
624 
625  XMLNodeTypes m_type;
626  XMLNodeLocation m_location;
627 
628  friend class XMLDocument;
629  friend class XMLElement;
630 };
631 
643 
644 // ----------------------------------------------------------------------------
645 
658 class PCL_CLASS XMLParseError : public Error
659 {
660 public:
661 
678  XMLParseError( const XMLNode& node, const String& whileDoing, const String& whatHappened )
679  : Error( whileDoing + node.Location().ToString() + ": " + whatHappened )
680  {
681  }
682 
699  XMLParseError( const XMLNodeLocation& where, const String& whileDoing, const String& whatHappened )
700  : Error( whileDoing + where.ToString() + ": " + whatHappened )
701  {
702  }
703 
707  XMLParseError( const XMLParseError& ) = default;
708 };
709 
710 // ----------------------------------------------------------------------------
711 
723 class PCL_CLASS XMLAttribute : public XMLComponent
724 {
725 public:
726 
731  XMLAttribute() = default;
732 
746  XMLAttribute( const String& name, const String& value = String() )
747  : m_name( name )
748  , m_value( value )
749  {
750  }
751 
755  XMLAttribute( const XMLAttribute& ) = default;
756 
760  const String& Name() const
761  {
762  return m_name;
763  }
764 
768  const String& Value() const
769  {
770  return m_value;
771  }
772 
776  void SetValue( const String& text )
777  {
778  m_value = text;
779  }
780 
787  {
788  return XML::EncodedText( m_value, false/*apos*/ );
789  }
790 
798  bool operator ==( const XMLAttribute& x ) const
799  {
800  return m_name == x.m_name;
801  }
802 
810  bool operator <( const XMLAttribute& x ) const
811  {
812  return m_name < x.m_name;
813  }
814 
815 private:
816 
817  String m_name;
818  String m_value;
819 };
820 
821 // ----------------------------------------------------------------------------
822 
837 class PCL_CLASS XMLAttributeList
838 {
839 public:
840 
846 
851 
856 
868  XMLAttributeList( const String& text )
869  {
870  Parse( text );
871  }
872 
876  XMLAttributeList() = default;
877 
881  XMLAttributeList( const XMLAttributeList& ) = default;
882 
886  int Length() const
887  {
888  return int( m_list.Length() );
889  }
890 
894  bool IsEmpty() const
895  {
896  return m_list.IsEmpty();
897  }
898 
904  const XMLAttribute& operator []( int i ) const
905  {
906  return m_list[i];
907  }
908 
913  const_iterator Begin() const
914  {
915  return m_list.Begin();
916  }
917 
922  const_iterator End() const
923  {
924  return m_list.End();
925  }
926 
927 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
928 
931  const_iterator begin() const
932  {
933  return Begin();
934  }
935 
939  const_iterator end() const
940  {
941  return End();
942  }
943 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
944 
949  bool HasAttribute( const String& name ) const
950  {
951  return m_list.Contains( name );
952  }
953 
959  String AttributeValue( const String& name ) const
960  {
961  const_iterator a = m_list.Search( name );
962  return (a != m_list.End()) ? a->Value() : String();
963  }
964 
980  void SetAttribute( const String& name, const String& value )
981  {
982  if ( !name.IsEmpty() )
983  {
984  iterator a = m_list.Search( name );
985  if ( a == m_list.End() )
986  m_list.Add( XMLAttribute( name, value ) );
987  else
988  a->SetValue( value );
989  }
990  }
991 
997  void SetAttribute( const XMLAttribute& attribute )
998  {
999  if ( !attribute.Name().IsEmpty() )
1000  {
1001  iterator a = m_list.Search( attribute );
1002  if ( a == m_list.End() )
1003  m_list.Add( attribute );
1004  else
1005  *a = attribute;
1006  }
1007  }
1008 
1015  {
1016  SetAttribute( attribute );
1017  return *this;
1018  }
1019 
1035  void SetAttributes( const XMLAttributeList& list )
1036  {
1037  for ( auto a : list )
1038  SetAttribute( a );
1039  }
1040 
1047  {
1048  SetAttributes( list );
1049  return *this;
1050  }
1051 
1057  void RemoveAttribute( const String& name )
1058  {
1059  iterator a = m_list.Search( name );
1060  if ( a != m_list.End() )
1061  m_list.Remove( a );
1062  }
1063 
1068  void Clear()
1069  {
1070  m_list.Clear();
1071  }
1072 
1077  void Sort()
1078  {
1079  m_list.Sort();
1080  }
1081 
1103  void Parse( const String& text );
1104 
1115  void Serialize( IsoString& text ) const;
1116 
1117 private:
1118 
1119  list_implementation m_list;
1120 };
1121 
1122 // ----------------------------------------------------------------------------
1123 
1137 class PCL_CLASS XMLElement : public XMLNode
1138 {
1139 public:
1140 
1144  typedef XMLNodeList::iterator iterator;
1145 
1149  typedef XMLNodeList::const_iterator const_iterator;
1150 
1156 
1161  : XMLNode( XMLNodeType::Element )
1162  {
1163  }
1164 
1169  XMLElement( const String& name, const XMLAttributeList& attributes = XMLAttributeList() )
1170  : XMLNode( XMLNodeType::Element )
1171  , m_name( name )
1172  , m_attributes( attributes )
1173  {
1174  }
1175 
1181  XMLElement( XMLElement& parent, const String& name, const XMLAttributeList& attributes = XMLAttributeList() )
1182  : XMLNode( XMLNodeType::Element )
1183  , m_name( name )
1184  , m_attributes( attributes )
1185  {
1186  parent.AddChildNode( this );
1187  }
1188 
1193  XMLElement( const XMLElement& ) = delete;
1194 
1199  XMLElement& operator =( const XMLElement& ) = delete;
1200 
1205  virtual ~XMLElement()
1206  {
1207  DestroyChildNodes();
1208  }
1209 
1220  bool IsRootElement() const
1221  {
1222  return ParentElement() == nullptr;
1223  }
1224 
1228  const String& Name() const
1229  {
1230  return m_name;
1231  }
1232 
1237  {
1238  return m_attributes;
1239  }
1240 
1244  bool HasAttributes() const
1245  {
1246  return !m_attributes.IsEmpty();
1247  }
1248 
1253  bool HasAttribute( const String& name ) const
1254  {
1255  return m_attributes.HasAttribute( name );
1256  }
1257 
1263  String AttributeValue( const String& name ) const
1264  {
1265  return m_attributes.AttributeValue( name );
1266  }
1267 
1283  void SetAttribute( const String& name, const String& value )
1284  {
1285  XMLAttribute a( name, value );
1286  a.m_parent = this;
1287  m_attributes.SetAttribute( a );
1288  }
1289 
1295  void SetAttribute( const XMLAttribute& attribute )
1296  {
1297  XMLAttribute a( attribute );
1298  a.m_parent = this;
1299  m_attributes.SetAttribute( a );
1300  }
1301 
1307  XMLElement& operator <<( const XMLAttribute& attribute )
1308  {
1309  SetAttribute( attribute );
1310  return *this;
1311  }
1312 
1328  void SetAttributes( const XMLAttributeList& list )
1329  {
1330  for ( auto a : list )
1331  SetAttribute( a );
1332  }
1333 
1340  {
1341  SetAttributes( list );
1342  return *this;
1343  }
1344 
1350  void RemoveAttribute( const String& name )
1351  {
1352  m_attributes.RemoveAttribute( name );
1353  }
1354 
1359  {
1360  m_attributes.Clear();
1361  }
1362 
1368  {
1369  m_attributes.Sort();
1370  }
1371 
1378  template <class BP>
1379  void SortAttributes( BP p )
1380  {
1381  m_attributes.Sort( p );
1382  }
1383 
1395  void ParseAttributes( const String& text )
1396  {
1397  XMLAttributeList list( text );
1398  ClearAttributes();
1399  SetAttributes( list );
1400  }
1401 
1412  void SerializeAttributes( IsoString& text ) const
1413  {
1414  m_attributes.Serialize( text );
1415  }
1416 
1420  int ChildCount() const
1421  {
1422  return int( m_childNodes.Length() );
1423  }
1424 
1429  bool IsEmpty() const
1430  {
1431  return m_childNodes.IsEmpty();
1432  }
1433 
1439  const XMLNode& operator []( int i ) const
1440  {
1441  return m_childNodes[i];
1442  }
1443 
1449  const XMLNode& First() const
1450  {
1451  return m_childNodes.First();
1452  }
1453 
1459  const XMLNode& Last() const
1460  {
1461  return m_childNodes.Last();
1462  }
1463 
1468  const_iterator Begin() const
1469  {
1470  return m_childNodes.Begin();
1471  }
1472 
1477  const_iterator End() const
1478  {
1479  return m_childNodes.End();
1480  }
1481 
1482 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
1483 
1486  const_iterator begin() const
1487  {
1488  return Begin();
1489  }
1490 
1494  const_iterator end() const
1495  {
1496  return End();
1497  }
1498 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
1499 
1500 #ifndef __PCL_NO_MUTABLE_XML_ELEMENT_ITERATORS
1501 
1506  iterator Begin()
1507  {
1508  return m_childNodes.Begin();
1509  }
1510 
1515  iterator End()
1516  {
1517  return m_childNodes.End();
1518  }
1519 
1524  const_iterator ConstBegin() const
1525  {
1526  return m_childNodes.ConstBegin();
1527  }
1528 
1533  const_iterator ConstEnd() const
1534  {
1535  return m_childNodes.ConstEnd();
1536  }
1537 
1538 # ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
1539 
1542  iterator begin()
1543  {
1544  return Begin();
1545  }
1546 
1550  iterator end()
1551  {
1552  return End();
1553  }
1554 # endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
1555 
1556 #endif // !__PCL_NO_MUTABLE_XML_ELEMENT_ITERATORS
1557 
1561  bool HasElements() const
1562  {
1563  return m_childTypes.IsFlagSet( XMLNodeType::Element );
1564  }
1565 
1569  bool HasText() const
1570  {
1571  return m_childTypes.IsFlagSet( XMLNodeType::Text );
1572  }
1573 
1577  bool HasCDATA() const
1578  {
1579  return m_childTypes.IsFlagSet( XMLNodeType::CDATA );
1580  }
1581 
1587  {
1588  return m_childTypes.IsFlagSet( XMLNodeType::ProcessingInstructions );
1589  }
1590 
1595  bool HasComments() const
1596  {
1597  return m_childTypes.IsFlagSet( XMLNodeType::Comment );
1598  }
1599 
1607  String Text() const;
1608 
1612  void GetChildElements( child_element_list& list, bool recursive ) const
1613  {
1614  for ( const XMLNode& node : m_childNodes )
1615  if ( node.IsElement() )
1616  {
1617  const XMLElement& element = static_cast<const XMLElement&>( node );
1618  list << &element;
1619  if ( recursive )
1620  element.GetChildElements( list, recursive );
1621  }
1622  }
1623 
1631  child_element_list ChildElements( bool recursive = false ) const
1632  {
1633  child_element_list list;
1634  GetChildElements( list, recursive );
1635  return list;
1636  }
1637 
1641  void GetChildElementsByName( child_element_list& list, const String& name, bool recursive ) const
1642  {
1643  for ( const XMLNode& node : m_childNodes )
1644  if ( node.IsElement() )
1645  {
1646  const XMLElement& element = static_cast<const XMLElement&>( node );
1647  if ( element.Name() == name )
1648  {
1649  list << &element;
1650  if ( recursive )
1651  element.GetChildElementsByName( list, name, recursive );
1652  }
1653  }
1654  }
1655 
1664  child_element_list ChildElementsByName( const String& name, bool recursive = false ) const
1665  {
1666  child_element_list list;
1667  GetChildElementsByName( list, name, recursive );
1668  return list;
1669  }
1670 
1674  void GetChildNodesByType( XMLNodeList& list, XMLNodeTypes types, bool recursive ) const
1675  {
1676  for ( const XMLNode& node : m_childNodes )
1677  if ( types.IsFlagSet( node.NodeType() ) )
1678  {
1679  list << &node;
1680  if ( recursive )
1681  if ( node.IsElement() )
1682  static_cast<const XMLElement&>( node ).GetChildNodesByType( list, types, recursive );
1683  }
1684  }
1685 
1695  XMLNodeList ChildNodesByType( XMLNodeTypes types, bool recursive = false ) const
1696  {
1697  XMLNodeList list;
1698  GetChildNodesByType( list, types, recursive );
1699  return list;
1700  }
1701 
1705  template <class UP>
1706  void GetChildNodesThat( XMLNodeList& list, UP u, bool recursive ) const
1707  {
1708  for ( const XMLNode& node : m_childNodes )
1709  if ( u( node ) )
1710  {
1711  list << &node;
1712  if ( recursive )
1713  if ( node.IsElement() )
1714  static_cast<const XMLElement&>( node ).GetChildNodesThat( list, u, recursive );
1715  }
1716  }
1717 
1729  template <class UP>
1730  XMLNodeList ChildNodesThat( UP u, bool recursive = false ) const
1731  {
1732  XMLNodeList list;
1733  GetChildNodesThat( list, u, recursive );
1734  return list;
1735  }
1736 
1743  void AddChildNode( XMLNode* node )
1744  {
1745  m_childNodes << node;
1746  node->m_parent = this;
1747  node->m_type.SetFlag( XMLNodeType::ChildNode );
1748  m_childTypes.SetFlag( node->NodeType() );
1749  }
1750 
1758  {
1759  AddChildNode( node );
1760  return *this;
1761  }
1762 
1770  void AddChildNodes( XMLNodeList& nodes )
1771  {
1772  for ( XMLNode& node : nodes )
1773  AddChildNode( &node );
1774  }
1775 
1782  XMLElement& operator <<( XMLNodeList& nodes )
1783  {
1784  AddChildNodes( nodes );
1785  return *this;
1786  }
1787 
1795  void AddChildNode( XMLNode* node, const XMLNodeLocation& location )
1796  {
1797  node->m_location = location;
1798  AddChildNode( node );
1799  }
1800 
1806  {
1807  m_childNodes.Destroy();
1808  m_childTypes = XMLNodeType::Undefined;
1809  }
1810 
1820  XMLNodeList ReleaseChildNodes()
1821  {
1822  XMLNodeList nodes = m_childNodes;
1823  m_childNodes.Clear();
1824  m_childTypes = XMLNodeType::Undefined;
1825  return nodes;
1826  }
1827 
1835  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
1836 
1837 private:
1838 
1839  String m_name;
1840  XMLAttributeList m_attributes;
1841  XMLNodeList m_childNodes;
1842  XMLNodeTypes m_childTypes = XMLNodeType::Undefined;
1843 };
1844 
1845 // ----------------------------------------------------------------------------
1846 
1858 
1859 // ----------------------------------------------------------------------------
1860 
1871 class PCL_CLASS XMLText : public XMLNode
1872 {
1873 public:
1874 
1900  XMLText( const String& text, bool preserveSpaces = true, bool verbatim = false )
1901  : XMLNode( XMLNodeType::Text )
1902  , m_text( preserveSpaces ? text : XML::CollapsedSpaces( XML::TrimmedSpaces( text ) ) )
1903  , m_preserveSpaces( preserveSpaces )
1904  , m_verbatim( verbatim )
1905  {
1906  }
1907 
1911  XMLText( const XMLText& ) = default;
1912 
1917  const String& Text() const
1918  {
1919  return m_text;
1920  }
1921 
1926  bool IsPreserveSpaces() const
1927  {
1928  return m_preserveSpaces;
1929  }
1930 
1937  {
1938  return XML::EncodedText( m_text );
1939  }
1940 
1949  String SpaceTransformedText( bool collapse, bool trim ) const
1950  {
1951  String text = m_text;
1952  if ( trim )
1953  text = XML::TrimmedSpaces( text );
1954  if ( collapse )
1955  text = XML::CollapsedSpaces( text );
1956  return text;
1957  }
1958 
1966  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
1967 
1977  bool NLAfter( const XMLNode& previous ) const override
1978  {
1979  return !m_preserveSpaces;
1980  }
1981 
1982 private:
1983 
1984  String m_text; // N.B.: This is plain, that is, decoded, text.
1985  bool m_preserveSpaces = true;
1986  bool m_verbatim = false;
1987 };
1988 
1989 // ----------------------------------------------------------------------------
1990 
2001 class PCL_CLASS XMLCDATA : public XMLNode
2002 {
2003 public:
2004 
2012  XMLCDATA( const String& data = String() )
2013  : XMLNode( XMLNodeType::CDATA )
2014  , m_cdata( data )
2015  {
2016  }
2017 
2021  XMLCDATA( const XMLCDATA& ) = default;
2022 
2027  const String& CData() const
2028  {
2029  return m_cdata;
2030  }
2031 
2037  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
2038 
2039 private:
2040 
2041  String m_cdata;
2042 };
2043 
2044 // ----------------------------------------------------------------------------
2045 
2058 {
2059 public:
2060 
2069  XMLProcessingInstructions( const String& target, const String& instructions )
2070  : XMLNode( XMLNodeType::ProcessingInstructions )
2071  , m_target( target )
2072  , m_instructions( instructions )
2073  {
2074  }
2075 
2080 
2084  const String& Target() const
2085  {
2086  return m_target;
2087  }
2088 
2092  const String& Instructions() const
2093  {
2094  return m_instructions;
2095  }
2096 
2102  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
2103 
2104 private:
2105 
2106  String m_target;
2107  String m_instructions;
2108 };
2109 
2110 // ----------------------------------------------------------------------------
2111 
2122 class PCL_CLASS XMLComment : public XMLNode
2123 {
2124 public:
2125 
2134  XMLComment( const String& comment )
2135  : XMLNode( XMLNodeType::Comment )
2136  , m_comment( comment )
2137  {
2138  }
2139 
2143  XMLComment( const XMLComment& ) = default;
2144 
2148  const String& Comment() const
2149  {
2150  return m_comment;
2151  }
2152 
2158  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
2159 
2160 private:
2161 
2162  String m_comment;
2163 };
2164 
2165 // ----------------------------------------------------------------------------
2166 
2179 class PCL_CLASS XMLUnknownElement : public XMLNode
2180 {
2181 public:
2182 
2187  XMLUnknownElement( const String& name, const String& parameters = String() )
2188  : XMLNode( XMLNodeType::Unknown )
2189  , m_name( name )
2190  , m_parameters( parameters )
2191  {
2192  }
2193 
2197  XMLUnknownElement( const XMLUnknownElement& ) = default;
2198 
2202  const String& Name() const
2203  {
2204  return m_name;
2205  }
2206 
2210  const String& Parameters() const
2211  {
2212  return m_parameters;
2213  }
2214 
2220  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
2221 
2222 private:
2223 
2224  String m_name;
2225  String m_parameters;
2226 };
2227 
2228 // ----------------------------------------------------------------------------
2229 
2240 class PCL_CLASS XMLDeclaration : public XMLComponent
2241 {
2242 public:
2243 
2248  XMLDeclaration( const String& version = String(), const String& encoding = String(), bool standalone = false )
2249  : m_version( version )
2250  , m_encoding( encoding )
2251  , m_standalone( standalone )
2252  {
2253  }
2254 
2258  XMLDeclaration( const XMLDeclaration& ) = default;
2259 
2263  const String& Version() const
2264  {
2265  return m_version;
2266  }
2267 
2271  const String& DocumentEncoding() const
2272  {
2273  return m_encoding;
2274  }
2275 
2280  {
2281  return m_standalone;
2282  }
2283 
2289  bool IsDefined() const
2290  {
2291  return !m_version.IsEmpty();
2292  }
2293 
2303  void Serialize( IsoString& text ) const;
2304 
2305 private:
2306 
2307  String m_version;
2308  String m_encoding;
2309  bool m_standalone = false;
2310 };
2311 
2312 // ----------------------------------------------------------------------------
2313 
2325 class PCL_CLASS XMLDocTypeDeclaration : public XMLComponent
2326 {
2327 public:
2328 
2333  XMLDocTypeDeclaration( const String& name = String(), const String& definition = String() )
2334  : m_name( name )
2335  , m_definition( definition )
2336  {
2337  }
2338 
2342  XMLDocTypeDeclaration( const XMLDocTypeDeclaration& ) = default;
2343 
2347  const String& Name() const
2348  {
2349  return m_name;
2350  }
2351 
2355  const String& Definition() const
2356  {
2357  return m_definition;
2358  }
2359 
2365  bool IsDefined() const
2366  {
2367  return !m_name.IsEmpty();
2368  }
2369 
2377  void Serialize( IsoString& text ) const;
2378 
2379 private:
2380 
2381  String m_name;
2382  String m_definition;
2383 };
2384 
2385 // ----------------------------------------------------------------------------
2386 
2415 {
2420  {
2421  }
2422 
2427  virtual bool operator()( const XMLElement* parent, const String& name ) const = 0;
2428 
2439  virtual bool operator()( const XMLElement* parent, const String& name, const XMLAttributeList& attributes ) const
2440  {
2441  return true;
2442  }
2443 };
2444 
2445 // ----------------------------------------------------------------------------
2446 
2460 namespace XMLParserOption
2461 {
2462  enum mask_type
2463  {
2464  IgnoreComments = 0x00000001,
2465  IgnoreUnknownElements = 0x00000002,
2466  IgnoreStrayCharacters = 0x00000004,
2467  NormalizeTextSpaces = 0x00000008
2468  };
2469 }
2470 
2477 
2478 // ----------------------------------------------------------------------------
2479 
2560 class PCL_CLASS XMLDocument
2561 {
2562 public:
2563 
2567  typedef XMLNodeList::iterator iterator;
2568 
2572  typedef XMLNodeList::const_iterator const_iterator;
2573 
2578  typedef XMLParserOption::mask_type parser_option;
2579 
2590  XMLDocument() = default;
2591 
2596  virtual ~XMLDocument()
2597  {
2598  m_nodes.Destroy();
2599  m_root = nullptr;
2600  RemoveElementFilter();
2601  }
2602 
2607  XMLDocument( const XMLDocument& ) = delete;
2608 
2613  XMLDocument& operator =( const XMLDocument& ) = delete;
2614 
2619  const XMLDeclaration& XML() const
2620  {
2621  return m_xml;
2622  }
2623 
2627  void SetXML( const XMLDeclaration& xml )
2628  {
2629  m_xml = xml;
2630  }
2631 
2636  void SetXML( const String& version = "1.0", const String& encoding = "UTF-8", bool standalone = false )
2637  {
2638  SetXML( XMLDeclaration( version, encoding, standalone ) );
2639  }
2640 
2646  {
2647  return m_docType;
2648  }
2649 
2654  void SetDocType( const XMLDocTypeDeclaration& docType )
2655  {
2656  m_docType = docType;
2657  }
2658 
2666  const XMLElement* RootElement() const
2667  {
2668  return m_root;
2669  }
2670 
2685  {
2686  XMLElement* root = m_root;
2687  m_nodes.RemovePointer( m_root );
2688  Clear();
2689  return root;
2690  }
2691 
2696  int NodeCount() const
2697  {
2698  return int( m_nodes.Length() );
2699  }
2700 
2705  bool IsEmpty() const
2706  {
2707  return m_nodes.IsEmpty();
2708  }
2709 
2715  const XMLNode& operator []( int i ) const
2716  {
2717  return m_nodes[i];
2718  }
2719 
2724  const_iterator Begin() const
2725  {
2726  return m_nodes.Begin();
2727  }
2728 
2733  const_iterator End() const
2734  {
2735  return m_nodes.End();
2736  }
2737 
2738 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
2739 
2742  const_iterator begin() const
2743  {
2744  return Begin();
2745  }
2746 
2750  const_iterator end() const
2751  {
2752  return End();
2753  }
2754 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
2755 
2770  void AddNode( XMLNode* node );
2771 
2778  {
2779  AddNode( node );
2780  return *this;
2781  }
2782 
2796  void SetRootElement( XMLElement* element );
2797 
2809  void Clear();
2810 
2821  {
2822  delete m_filter, m_filter = filter;
2823  }
2824 
2831  {
2832  SetElementFilter( nullptr );
2833  }
2834 
2840  void SetParserOption( parser_option option, bool on = true )
2841  {
2842  m_parserOptions.SetFlag( option, on );
2843  }
2844 
2850  void SetParserOptions( XMLParserOptions options )
2851  {
2852  m_parserOptions = options;
2853  }
2854 
2860  {
2861  m_parserOptions.Clear();
2862  }
2863 
2876  void Parse( const String& text );
2877 
2897  bool IsAutoFormatting() const
2898  {
2899  return m_autoFormatting;
2900  }
2901 
2906  void EnableAutoFormatting( bool enable = true )
2907  {
2908  m_autoFormatting = enable;
2909  }
2910 
2915  void DisableAutoFormatting( bool disable = true )
2916  {
2917  EnableAutoFormatting( !disable );
2918  }
2919 
2929  int IndentSize() const
2930  {
2931  return m_indentSize;
2932  }
2933 
2957  void SetIndentSize( int indentSize )
2958  {
2959  m_indentSize = Range( indentSize, 0, 8 );
2960  }
2961 
2970  bool IsIndentTabs() const
2971  {
2972  return m_indentTabs;
2973  }
2974 
2979  void EnableIndentTabs( bool enable = true )
2980  {
2981  m_indentTabs = enable;
2982  }
2983 
2988  void DisableIndentTabs( bool disable = true )
2989  {
2990  EnableIndentTabs( !disable );
2991  }
2992 
3004  IsoString Serialize() const;
3005 
3015  void SerializeToFile( const String& path ) const;
3016 
3017 private:
3018 
3019  XMLDeclaration m_xml;
3020  XMLDocTypeDeclaration m_docType;
3021  XMLNodeList m_nodes;
3022  XMLElement* m_root = nullptr;
3023  XMLElementFilter* m_filter = nullptr;
3024  XMLParserOptions m_parserOptions;
3025  XMLNodeLocation m_location;
3026  bool m_autoFormatting = false;
3027  bool m_indentTabs = false;
3028  int m_indentSize = 3;
3029 };
3030 
3031 // ----------------------------------------------------------------------------
3032 
3033 } // pcl
3034 
3035 #endif // __PCL_XML_h
3036 
3037 // ----------------------------------------------------------------------------
3038 // EOF pcl/XML.h - Released 2020-08-25T19:17:02Z
child_element_list ChildElements(bool recursive=false) const
Definition: XML.h:1631
bool IsChildNode() const
Definition: XML.h:542
XMLElement * ParentElement() const
Definition: XML.h:353
void SortAttributes(BP p)
Definition: XML.h:1379
Dynamic list of XML node objects.
iterator End()
Definition: XML.h:1515
bool IsElement() const
Definition: XML.h:559
XMLAttribute(const String &name, const String &value=String())
Definition: XML.h:746
const_iterator End() const
Definition: XML.h:1477
Abstract base class of all XML document node classes.
Definition: XML.h:499
void SetXML(const XMLDeclaration &xml)
Definition: XML.h:2627
Root base class of all XML document components.
Definition: XML.h:334
bool HasAttribute(const String &name) const
Definition: XML.h:949
void ParseAttributes(const String &text)
Definition: XML.h:1395
static bool IsWhiteSpaceChar(T c)
Definition: XML.h:117
bool IsEmpty() const
Definition: XML.h:1429
const XMLNodeLocation & Location() const
Definition: XML.h:585
const_iterator Begin() const
Definition: XML.h:2724
const String & Instructions() const
Definition: XML.h:2092
node_type NodeType() const
Definition: XML.h:550
XMLNodeType::mask_type node_type
Definition: XML.h:507
int ChildCount() const
Definition: XML.h:1420
void SetAttributes(const XMLAttributeList &list)
Definition: XML.h:1328
A functional class for filtering XML elements.
Definition: XML.h:2414
const String & Name() const
Definition: XML.h:760
XMLNode(node_type type)
Definition: XML.h:514
XML DOCTYPE declaration
Definition: XML.h:2325
XML element attribute
Definition: XML.h:723
const String & Value() const
Definition: XML.h:768
Array< XMLAttribute > list_implementation
Definition: XML.h:845
void SetValue(const String &text)
Definition: XML.h:776
XMLComment(const String &comment)
Definition: XML.h:2134
PCL root namespace.
Definition: AbstractImage.h:76
static bool IsNameStartChar(T c)
Definition: XML.h:149
XMLAttributeList Attributes() const
Definition: XML.h:1236
String AsString(mask_type type)
XML comment section
Definition: XML.h:2122
child_element_list ChildElementsByName(const String &name, bool recursive=false) const
Definition: XML.h:1664
const String & Name() const
Definition: XML.h:1228
XML declaration
Definition: XML.h:2240
ReferenceArray< XMLElement > child_element_list
Definition: XML.h:1155
string_base::const_iterator const_iterator
Definition: String.h:7974
XML parsing error with automatic text location information generation
Definition: XML.h:658
iterator End()
Definition: String.h:976
XMLParserOption::mask_type parser_option
Definition: XML.h:2578
int Length() const
Definition: XML.h:886
String EncodedValue() const
Definition: XML.h:786
bool IsEmpty() const
Definition: String.h:788
static bool IsValidName(const String &name)
Definition: XML.h:207
String EncodedText() const
Definition: XML.h:1936
A collection of XML node types.
static String ReferenceValue(const String &reference)
Definition: XML.h:316
virtual ~XMLElement()
Definition: XML.h:1205
int NodeCount() const
Definition: XML.h:2696
bool IsDefined() const
Definition: XML.h:2365
const_iterator begin() const
Definition: XML.h:1486
bool HasComments() const
Definition: XML.h:1595
XMLAttributeList(const String &text)
Definition: XML.h:868
void RemoveAttribute(const String &name)
Definition: XML.h:1350
const_iterator Begin() const
Definition: XML.h:1468
String SpaceTransformedText(bool collapse, bool trim) const
Definition: XML.h:1949
const String & Target() const
Definition: XML.h:2084
Utility functions and data for XML document parsing and generation.
Definition: XML.h:84
void SetAttributes(const XMLAttributeList &list)
Definition: XML.h:1035
XML document parsing and generation
Definition: XML.h:2560
XMLUnknownElement(const String &name, const String &parameters=String())
Definition: XML.h:2187
void EnableIndentTabs(bool enable=true)
Definition: XML.h:2979
const String & DocumentEncoding() const
Definition: XML.h:2271
Array< T, A > & operator<<(Array< T, A > &x, const V &v)
Definition: Array.h:2120
XMLNodeList ChildNodesThat(UP u, bool recursive=false) const
Definition: XML.h:1730
void EnableAutoFormatting(bool enable=true)
Definition: XML.h:2906
bool IsEmpty() const
Definition: XML.h:2705
XMLDocTypeDeclaration(const String &name=String(), const String &definition=String())
Definition: XML.h:2333
static bool IsNameChar(T c)
Definition: XML.h:175
iterator end()
Definition: XML.h:1550
XML text block
Definition: XML.h:1871
list_implementation::iterator iterator
Definition: XML.h:850
XMLProcessingInstructions(const String &target, const String &instructions)
Definition: XML.h:2069
constexpr const T & Range(const T &x, const T &a, const T &b)
Definition: Utility.h:190
void SetElementFilter(XMLElementFilter *filter)
Definition: XML.h:2820
static bool IsSpaceChar(T c)
Definition: XML.h:138
const String & Comment() const
Definition: XML.h:2148
XMLNode(const XMLNode &x)
Definition: XML.h:526
void ClearParserOptions()
Definition: XML.h:2859
bool IsStandaloneDocument() const
Definition: XML.h:2279
void SetAttribute(const XMLAttribute &attribute)
Definition: XML.h:1295
XMLElement(XMLElement &parent, const String &name, const XMLAttributeList &attributes=XMLAttributeList())
Definition: XML.h:1181
void SerializeAttributes(IsoString &text) const
Definition: XML.h:1412
int IndentSize() const
Definition: XML.h:2929
void SetXML(const String &version="1.0", const String &encoding="UTF-8", bool standalone=false)
Definition: XML.h:2636
XMLNodeList ChildNodesByType(XMLNodeTypes types, bool recursive=false) const
Definition: XML.h:1695
static bool IsRestrictedChar(T c)
Definition: XML.h:192
bool IsEmpty() const
Definition: XML.h:894
Unicode (UTF-16) string.
Definition: String.h:7916
bool NLAfter(const XMLNode &previous) const override
Definition: XML.h:1977
const String & Name() const
Definition: XML.h:2347
void ClearAttributes()
Definition: XML.h:1358
XMLNodeList::const_iterator const_iterator
Definition: XML.h:2572
static String CollapsedSpaces(String::const_iterator i, String::const_iterator j)
const_iterator ConstBegin() const
Definition: XML.h:1524
Dynamic list of XML elements.
static String EncodedText(String::const_iterator i, String::const_iterator j, bool apos=true)
Definition: XML.h:278
bool IsRootElement() const
Definition: XML.h:1220
const String & CData() const
Definition: XML.h:2027
void SetParserOption(parser_option option, bool on=true)
Definition: XML.h:2840
virtual ~XMLElementFilter()
Definition: XML.h:2419
void DisableIndentTabs(bool disable=true)
Definition: XML.h:2988
const_iterator begin() const
Definition: XML.h:931
bool HasText() const
Definition: XML.h:1569
XMLText(const String &text, bool preserveSpaces=true, bool verbatim=false)
Definition: XML.h:1900
bool IsTopLevel() const
Definition: XML.h:362
XMLNodeList ReleaseChildNodes()
Definition: XML.h:1820
const_iterator Begin() const
Definition: XML.h:913
bool IsText() const
Definition: XML.h:568
XMLParseError(const XMLNode &node, const String &whileDoing, const String &whatHappened)
Definition: XML.h:678
virtual ~XMLDocument()
Definition: XML.h:2596
void DisableAutoFormatting(bool disable=true)
Definition: XML.h:2915
void SortAttributes()
Definition: XML.h:1367
bool IsAutoFormatting() const
Definition: XML.h:2897
bool HasAttributes() const
Definition: XML.h:1244
bool IsDefined() const
Definition: XML.h:2289
void RemoveElementFilter()
Definition: XML.h:2830
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2)
Definition: Array.h:2103
bool HasElements() const
Definition: XML.h:1561
void RemoveAttribute(const String &name)
Definition: XML.h:1057
void SetIndentSize(int indentSize)
Definition: XML.h:2957
String AttributeValue(const String &name) const
Definition: XML.h:959
A simple exception with an associated error message.
Definition: Exception.h:238
const_iterator end() const
Definition: XML.h:2750
void AddChildNodes(XMLNodeList &nodes)
Definition: XML.h:1770
XML element
Definition: XML.h:1137
const_iterator end() const
Definition: XML.h:1494
iterator Begin()
Definition: XML.h:1506
void SetAttribute(const String &name, const String &value)
Definition: XML.h:980
const String & Text() const
Definition: XML.h:1917
XMLElement(const String &name, const XMLAttributeList &attributes=XMLAttributeList())
Definition: XML.h:1169
void AddChildNode(XMLNode *node)
Definition: XML.h:1743
list_implementation::const_iterator const_iterator
Definition: XML.h:855
void DestroyChildNodes()
Definition: XML.h:1805
bool HasProcessingInstructions() const
Definition: XML.h:1586
const_iterator begin() const
Definition: XML.h:2742
XMLParseError(const XMLNodeLocation &where, const String &whileDoing, const String &whatHappened)
Definition: XML.h:699
FlagType< std::is_unsigned< enum_type >::value >::type flag_type
Definition: Flags.h:100
void SetDocType(const XMLDocTypeDeclaration &docType)
Definition: XML.h:2654
virtual bool operator()(const XMLElement *parent, const String &name, const XMLAttributeList &attributes) const
Definition: XML.h:2439
static bool IsLineBreakChar(T c)
Definition: XML.h:127
XML processing instructions
Definition: XML.h:2057
Dynamic list of XML element attributes.
Definition: XML.h:837
const XMLNode & Last() const
Definition: XML.h:1459
bool IsIndentTabs() const
Definition: XML.h:2970
void SetAttribute(const XMLAttribute &attribute)
Definition: XML.h:997
bool IsComment() const
Definition: XML.h:577
XMLElement * ReleaseRootElement()
Definition: XML.h:2684
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2)
Definition: Array.h:2092
A collection of XML document parsing options.
XMLNodeList::iterator iterator
Definition: XML.h:2567
XMLDeclaration(const String &version=String(), const String &encoding=String(), bool standalone=false)
Definition: XML.h:2248
const XMLNode & First() const
Definition: XML.h:1449
const XMLDocTypeDeclaration & DocType() const
Definition: XML.h:2645
XMLNodeLocation(int line_, int column_)
Definition: XML.h:460
const String & Definition() const
Definition: XML.h:2355
const_iterator End() const
Definition: XML.h:2733
String AttributeValue(const String &name) const
Definition: XML.h:1263
const_iterator End() const
Definition: XML.h:922
const_iterator ConstEnd() const
Definition: XML.h:1533
static String TrimmedSpaces(String::const_iterator i, String::const_iterator j)
const XMLDeclaration & XML() const
Definition: XML.h:2619
iterator begin()
Definition: XML.h:1542
const String & Name() const
Definition: XML.h:2202
const XMLElement * RootElement() const
Definition: XML.h:2666
const String & Parameters() const
Definition: XML.h:2210
void SetAttribute(const String &name, const String &value)
Definition: XML.h:1283
XML CDATA section
Definition: XML.h:2001
XMLNodeList::const_iterator const_iterator
Definition: XML.h:1149
bool IsPreserveSpaces() const
Definition: XML.h:1926
const String & Version() const
Definition: XML.h:2263
unsigned int uint32
Definition: Defs.h:600
signed long long int64
Definition: Defs.h:610
Source code location of a parsed XML document node.
Definition: XML.h:429
bool HasAttribute(const String &name) const
Definition: XML.h:1253
iterator Begin()
Definition: String.h:946
virtual ~XMLNode()
Definition: XML.h:535
const_iterator end() const
Definition: XML.h:939
void SetParserOptions(XMLParserOptions options)
Definition: XML.h:2850
Unsupported or invalid XML element.
Definition: XML.h:2179
XMLNodeList::iterator iterator
Definition: XML.h:1144
bool HasCDATA() const
Definition: XML.h:1577
Eight-bit string (ISO/IEC-8859-1 or UTF-8 string)
Definition: String.h:5390