PCL
XML.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.1.19
6 // ----------------------------------------------------------------------------
7 // pcl/XML.h - Released 2019-11-07T10:59:34Z
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-2019 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 (http://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_ ), column( column_ )
462  {
463  }
464 
468  XMLNodeLocation( const XMLNodeLocation& ) = default;
469 
482  String ToString() const;
483 };
484 
485 // ----------------------------------------------------------------------------
486 
498 class PCL_CLASS XMLNode : public XMLComponent
499 {
500 public:
501 
506  typedef XMLNodeType::mask_type node_type;
507 
513  XMLNode( node_type type ) :
514  XMLComponent(), m_type( type ), m_location()
515  {
516  }
517 
525  XMLNode( const XMLNode& x ) :
526  XMLComponent(), m_type( x.NodeType() ), m_location( x.m_location )
527  {
528  }
529 
533  virtual ~XMLNode()
534  {
535  }
536 
540  bool IsChildNode() const
541  {
542  return m_type.IsFlagSet( XMLNodeType::ChildNode );
543  }
544 
548  node_type NodeType() const
549  {
550  return static_cast<node_type>( XMLNodeTypes::flag_type( m_type & unsigned( ~XMLNodeType::ChildNode ) ) );
551  }
552 
557  bool IsElement() const
558  {
559  return NodeType() == XMLNodeType::Element;
560  }
561 
566  bool IsText() const
567  {
568  return NodeType() == XMLNodeType::Text;
569  }
570 
575  bool IsComment() const
576  {
577  return NodeType() == XMLNodeType::Comment;
578  }
579 
583  const XMLNodeLocation& Location() const
584  {
585  return m_location;
586  }
587 
613  virtual void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const = 0;
614 
619  virtual bool NLAfter( const XMLNode& previous ) const;
620 
621 private:
622 
623  XMLNodeTypes m_type;
624  XMLNodeLocation m_location;
625 
626  friend class XMLDocument;
627  friend class XMLElement;
628 };
629 
641 
642 // ----------------------------------------------------------------------------
643 
656 class PCL_CLASS XMLParseError : public Error
657 {
658 public:
659 
676  XMLParseError( const XMLNode& node, const String& whileDoing, const String& whatHappened ) :
677  Error( whileDoing + node.Location().ToString() + ": " + whatHappened )
678  {
679  }
680 
697  XMLParseError( const XMLNodeLocation& where, const String& whileDoing, const String& whatHappened ) :
698  Error( whileDoing + where.ToString() + ": " + whatHappened )
699  {
700  }
701 
705  XMLParseError( const XMLParseError& ) = default;
706 };
707 
708 // ----------------------------------------------------------------------------
709 
721 class PCL_CLASS XMLAttribute : public XMLComponent
722 {
723 public:
724 
729  XMLAttribute() = default;
730 
744  XMLAttribute( const String& name, const String& value = String() ) :
745  XMLComponent(),
746  m_name( name ),
747  m_value( value )
748  {
749  }
750 
754  XMLAttribute( const XMLAttribute& ) = default;
755 
759  const String& Name() const
760  {
761  return m_name;
762  }
763 
767  const String& Value() const
768  {
769  return m_value;
770  }
771 
775  void SetValue( const String& text )
776  {
777  m_value = text;
778  }
779 
786  {
787  return XML::EncodedText( m_value, false/*apos*/ );
788  }
789 
797  bool operator ==( const XMLAttribute& x ) const
798  {
799  return m_name == x.m_name;
800  }
801 
809  bool operator <( const XMLAttribute& x ) const
810  {
811  return m_name < x.m_name;
812  }
813 
814 private:
815 
816  String m_name;
817  String m_value;
818 };
819 
820 // ----------------------------------------------------------------------------
821 
836 class PCL_CLASS XMLAttributeList
837 {
838 public:
839 
845 
850 
855 
867  XMLAttributeList( const String& text )
868  {
869  Parse( text );
870  }
871 
875  XMLAttributeList() = default;
876 
880  XMLAttributeList( const XMLAttributeList& ) = default;
881 
885  int Length() const
886  {
887  return int( m_list.Length() );
888  }
889 
893  bool IsEmpty() const
894  {
895  return m_list.IsEmpty();
896  }
897 
903  const XMLAttribute& operator []( int i ) const
904  {
905  return m_list[i];
906  }
907 
912  const_iterator Begin() const
913  {
914  return m_list.Begin();
915  }
916 
921  const_iterator End() const
922  {
923  return m_list.End();
924  }
925 
926 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
927 
930  const_iterator begin() const
931  {
932  return Begin();
933  }
934 
938  const_iterator end() const
939  {
940  return End();
941  }
942 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
943 
948  bool HasAttribute( const String& name ) const
949  {
950  return m_list.Contains( name );
951  }
952 
958  String AttributeValue( const String& name ) const
959  {
960  const_iterator a = m_list.Search( name );
961  return (a != m_list.End()) ? a->Value() : String();
962  }
963 
979  void SetAttribute( const String& name, const String& value )
980  {
981  if ( !name.IsEmpty() )
982  {
983  iterator a = m_list.Search( name );
984  if ( a == m_list.End() )
985  m_list.Add( XMLAttribute( name, value ) );
986  else
987  a->SetValue( value );
988  }
989  }
990 
996  void SetAttribute( const XMLAttribute& attribute )
997  {
998  if ( !attribute.Name().IsEmpty() )
999  {
1000  iterator a = m_list.Search( attribute );
1001  if ( a == m_list.End() )
1002  m_list.Add( attribute );
1003  else
1004  *a = attribute;
1005  }
1006  }
1007 
1014  {
1015  SetAttribute( attribute );
1016  return *this;
1017  }
1018 
1034  void SetAttributes( const XMLAttributeList& list )
1035  {
1036  for ( auto a : list )
1037  SetAttribute( a );
1038  }
1039 
1046  {
1047  SetAttributes( list );
1048  return *this;
1049  }
1050 
1056  void RemoveAttribute( const String& name )
1057  {
1058  iterator a = m_list.Search( name );
1059  if ( a != m_list.End() )
1060  m_list.Remove( a );
1061  }
1062 
1067  void Clear()
1068  {
1069  m_list.Clear();
1070  }
1071 
1076  void Sort()
1077  {
1078  m_list.Sort();
1079  }
1080 
1102  void Parse( const String& text );
1103 
1114  void Serialize( IsoString& text ) const;
1115 
1116 private:
1117 
1118  list_implementation m_list;
1119 };
1120 
1121 // ----------------------------------------------------------------------------
1122 
1136 class PCL_CLASS XMLElement : public XMLNode
1137 {
1138 public:
1139 
1143  typedef XMLNodeList::iterator iterator;
1144 
1148  typedef XMLNodeList::const_iterator const_iterator;
1149 
1155 
1160  XMLNode( XMLNodeType::Element )
1161  {
1162  }
1163 
1168  XMLElement( const String& name, const XMLAttributeList& attributes = XMLAttributeList() ) :
1169  XMLNode( XMLNodeType::Element ),
1170  m_name( name ),
1171  m_attributes( attributes )
1172  {
1173  }
1174 
1180  XMLElement( XMLElement& parent, const String& name, const XMLAttributeList& attributes = XMLAttributeList() ) :
1181  XMLNode( XMLNodeType::Element ),
1182  m_name( name ),
1183  m_attributes( attributes )
1184  {
1185  parent.AddChildNode( this );
1186  }
1187 
1192  XMLElement( const XMLElement& ) = delete;
1193 
1198  XMLElement& operator =( const XMLElement& ) = delete;
1199 
1204  virtual ~XMLElement()
1205  {
1206  DestroyChildNodes();
1207  }
1208 
1219  bool IsRootElement() const
1220  {
1221  return ParentElement() == nullptr;
1222  }
1223 
1227  const String& Name() const
1228  {
1229  return m_name;
1230  }
1231 
1236  {
1237  return m_attributes;
1238  }
1239 
1243  bool HasAttributes() const
1244  {
1245  return !m_attributes.IsEmpty();
1246  }
1247 
1252  bool HasAttribute( const String& name ) const
1253  {
1254  return m_attributes.HasAttribute( name );
1255  }
1256 
1262  String AttributeValue( const String& name ) const
1263  {
1264  return m_attributes.AttributeValue( name );
1265  }
1266 
1282  void SetAttribute( const String& name, const String& value )
1283  {
1284  XMLAttribute a( name, value );
1285  a.m_parent = this;
1286  m_attributes.SetAttribute( a );
1287  }
1288 
1294  void SetAttribute( const XMLAttribute& attribute )
1295  {
1296  XMLAttribute a( attribute );
1297  a.m_parent = this;
1298  m_attributes.SetAttribute( a );
1299  }
1300 
1306  XMLElement& operator <<( const XMLAttribute& attribute )
1307  {
1308  SetAttribute( attribute );
1309  return *this;
1310  }
1311 
1327  void SetAttributes( const XMLAttributeList& list )
1328  {
1329  for ( auto a : list )
1330  SetAttribute( a );
1331  }
1332 
1339  {
1340  SetAttributes( list );
1341  return *this;
1342  }
1343 
1349  void RemoveAttribute( const String& name )
1350  {
1351  m_attributes.RemoveAttribute( name );
1352  }
1353 
1358  {
1359  m_attributes.Clear();
1360  }
1361 
1367  {
1368  m_attributes.Sort();
1369  }
1370 
1377  template <class BP>
1378  void SortAttributes( BP p )
1379  {
1380  m_attributes.Sort( p );
1381  }
1382 
1394  void ParseAttributes( const String& text )
1395  {
1396  XMLAttributeList list( text );
1397  ClearAttributes();
1398  SetAttributes( list );
1399  }
1400 
1411  void SerializeAttributes( IsoString& text ) const
1412  {
1413  m_attributes.Serialize( text );
1414  }
1415 
1419  int ChildCount() const
1420  {
1421  return int( m_childNodes.Length() );
1422  }
1423 
1428  bool IsEmpty() const
1429  {
1430  return m_childNodes.IsEmpty();
1431  }
1432 
1438  const XMLNode& operator []( int i ) const
1439  {
1440  return m_childNodes[i];
1441  }
1442 
1448  const XMLNode& First() const
1449  {
1450  return m_childNodes.First();
1451  }
1452 
1458  const XMLNode& Last() const
1459  {
1460  return m_childNodes.Last();
1461  }
1462 
1467  const_iterator Begin() const
1468  {
1469  return m_childNodes.Begin();
1470  }
1471 
1476  const_iterator End() const
1477  {
1478  return m_childNodes.End();
1479  }
1480 
1481 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
1482 
1485  const_iterator begin() const
1486  {
1487  return Begin();
1488  }
1489 
1493  const_iterator end() const
1494  {
1495  return End();
1496  }
1497 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
1498 
1502  bool HasElements() const
1503  {
1504  return m_childTypes.IsFlagSet( XMLNodeType::Element );
1505  }
1506 
1510  bool HasText() const
1511  {
1512  return m_childTypes.IsFlagSet( XMLNodeType::Text );
1513  }
1514 
1518  bool HasCDATA() const
1519  {
1520  return m_childTypes.IsFlagSet( XMLNodeType::CDATA );
1521  }
1522 
1528  {
1529  return m_childTypes.IsFlagSet( XMLNodeType::ProcessingInstructions );
1530  }
1531 
1536  bool HasComments() const
1537  {
1538  return m_childTypes.IsFlagSet( XMLNodeType::Comment );
1539  }
1540 
1548  String Text() const;
1549 
1553  void GetChildElements( child_element_list& list, bool recursive ) const
1554  {
1555  for ( const XMLNode& node : m_childNodes )
1556  if ( node.IsElement() )
1557  {
1558  const XMLElement& element = static_cast<const XMLElement&>( node );
1559  list << &element;
1560  if ( recursive )
1561  element.GetChildElements( list, recursive );
1562  }
1563  }
1564 
1572  child_element_list ChildElements( bool recursive = false ) const
1573  {
1574  child_element_list list;
1575  GetChildElements( list, recursive );
1576  return list;
1577  }
1578 
1582  void GetChildElementsByName( child_element_list& list, const String& name, bool recursive ) const
1583  {
1584  for ( const XMLNode& node : m_childNodes )
1585  if ( node.IsElement() )
1586  {
1587  const XMLElement& element = static_cast<const XMLElement&>( node );
1588  if ( element.Name() == name )
1589  {
1590  list << &element;
1591  if ( recursive )
1592  element.GetChildElementsByName( list, name, recursive );
1593  }
1594  }
1595  }
1596 
1605  child_element_list ChildElementsByName( const String& name, bool recursive = false ) const
1606  {
1607  child_element_list list;
1608  GetChildElementsByName( list, name, recursive );
1609  return list;
1610  }
1611 
1615  void GetChildNodesByType( XMLNodeList& list, XMLNodeTypes types, bool recursive ) const
1616  {
1617  for ( const XMLNode& node : m_childNodes )
1618  if ( types.IsFlagSet( node.NodeType() ) )
1619  {
1620  list << &node;
1621  if ( recursive )
1622  if ( node.IsElement() )
1623  static_cast<const XMLElement&>( node ).GetChildNodesByType( list, types, recursive );
1624  }
1625  }
1626 
1636  XMLNodeList ChildNodesByType( XMLNodeTypes types, bool recursive = false ) const
1637  {
1638  XMLNodeList list;
1639  GetChildNodesByType( list, types, recursive );
1640  return list;
1641  }
1642 
1646  template <class UP>
1647  void GetChildNodesThat( XMLNodeList& list, UP u, bool recursive ) const
1648  {
1649  for ( const XMLNode& node : m_childNodes )
1650  if ( u( node ) )
1651  {
1652  list << &node;
1653  if ( recursive )
1654  if ( node.IsElement() )
1655  static_cast<const XMLElement&>( node ).GetChildNodesThat( list, u, recursive );
1656  }
1657  }
1658 
1670  template <class UP>
1671  XMLNodeList ChildNodesThat( UP u, bool recursive = false ) const
1672  {
1673  XMLNodeList list;
1674  GetChildNodesThat( list, u, recursive );
1675  return list;
1676  }
1677 
1684  void AddChildNode( XMLNode* node )
1685  {
1686  m_childNodes << node;
1687  node->m_parent = this;
1688  node->m_type.SetFlag( XMLNodeType::ChildNode );
1689  m_childTypes.SetFlag( node->NodeType() );
1690  }
1691 
1699  {
1700  AddChildNode( node );
1701  return *this;
1702  }
1703 
1711  void AddChildNodes( XMLNodeList& nodes )
1712  {
1713  for ( XMLNode& node : nodes )
1714  AddChildNode( &node );
1715  }
1716 
1723  XMLElement& operator <<( XMLNodeList& nodes )
1724  {
1725  AddChildNodes( nodes );
1726  return *this;
1727  }
1728 
1736  void AddChildNode( XMLNode* node, const XMLNodeLocation& location )
1737  {
1738  node->m_location = location;
1739  AddChildNode( node );
1740  }
1741 
1747  {
1748  m_childNodes.Destroy();
1749  m_childTypes = XMLNodeType::Undefined;
1750  }
1751 
1761  XMLNodeList ReleaseChildNodes()
1762  {
1763  XMLNodeList nodes = m_childNodes;
1764  m_childNodes.Clear();
1765  m_childTypes = XMLNodeType::Undefined;
1766  return nodes;
1767  }
1768 
1776  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
1777 
1778 private:
1779 
1780  String m_name;
1781  XMLAttributeList m_attributes;
1782  XMLNodeList m_childNodes;
1783  XMLNodeTypes m_childTypes = XMLNodeType::Undefined;
1784 };
1785 
1786 // ----------------------------------------------------------------------------
1787 
1799 
1800 // ----------------------------------------------------------------------------
1801 
1812 class PCL_CLASS XMLText : public XMLNode
1813 {
1814 public:
1815 
1833  XMLText( const String& text, bool preserveSpaces = true ) :
1834  XMLNode( XMLNodeType::Text ),
1835  m_text( preserveSpaces ? text : XML::CollapsedSpaces( XML::TrimmedSpaces( text ) ) ),
1836  m_preserveSpaces( preserveSpaces )
1837  {
1838  }
1839 
1843  XMLText( const XMLText& ) = default;
1844 
1849  const String& Text() const
1850  {
1851  return m_text;
1852  }
1853 
1858  bool IsPreserveSpaces() const
1859  {
1860  return m_preserveSpaces;
1861  }
1862 
1869  {
1870  return XML::EncodedText( m_text );
1871  }
1872 
1881  String SpaceTransformedText( bool collapse, bool trim ) const
1882  {
1883  String text = m_text;
1884  if ( trim )
1885  text = XML::TrimmedSpaces( text );
1886  if ( collapse )
1887  text = XML::CollapsedSpaces( text );
1888  return text;
1889  }
1890 
1898  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
1899 
1909  bool NLAfter( const XMLNode& previous ) const override
1910  {
1911  return !m_preserveSpaces;
1912  }
1913 
1914 private:
1915 
1916  String m_text; // N.B.: This is plain, that is, decoded, text.
1917  bool m_preserveSpaces : 1;
1918 };
1919 
1920 // ----------------------------------------------------------------------------
1921 
1932 class PCL_CLASS XMLCDATA : public XMLNode
1933 {
1934 public:
1935 
1943  XMLCDATA( const String& data ) :
1944  XMLNode( XMLNodeType::CDATA ),
1945  m_cdata( data )
1946  {
1947  }
1948 
1952  XMLCDATA( const XMLCDATA& ) = default;
1953 
1958  const String& CData() const
1959  {
1960  return m_cdata;
1961  }
1962 
1968  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
1969 
1970 private:
1971 
1972  String m_cdata;
1973 };
1974 
1975 // ----------------------------------------------------------------------------
1976 
1989 {
1990 public:
1991 
2000  XMLProcessingInstructions( const String& target, const String& instructions ) :
2001  XMLNode( XMLNodeType::ProcessingInstructions ),
2002  m_target( target ),
2003  m_instructions( instructions )
2004  {
2005  }
2006 
2011 
2015  const String& Target() const
2016  {
2017  return m_target;
2018  }
2019 
2023  const String& Instructions() const
2024  {
2025  return m_instructions;
2026  }
2027 
2033  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
2034 
2035 private:
2036 
2037  String m_target;
2038  String m_instructions;
2039 };
2040 
2041 // ----------------------------------------------------------------------------
2042 
2053 class PCL_CLASS XMLComment : public XMLNode
2054 {
2055 public:
2056 
2065  XMLComment( const String& comment ) :
2066  XMLNode( XMLNodeType::Comment ),
2067  m_comment( comment )
2068  {
2069  }
2070 
2074  XMLComment( const XMLComment& ) = default;
2075 
2079  const String& Comment() const
2080  {
2081  return m_comment;
2082  }
2083 
2089  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
2090 
2091 private:
2092 
2093  String m_comment;
2094 };
2095 
2096 // ----------------------------------------------------------------------------
2097 
2110 class PCL_CLASS XMLUnknownElement : public XMLNode
2111 {
2112 public:
2113 
2118  XMLUnknownElement( const String& name, const String& parameters = String() ) :
2119  XMLNode( XMLNodeType::Unknown ),
2120  m_name( name ),
2121  m_parameters( parameters )
2122  {
2123  }
2124 
2128  XMLUnknownElement( const XMLUnknownElement& ) = default;
2129 
2133  const String& Name() const
2134  {
2135  return m_name;
2136  }
2137 
2141  const String& Parameters() const
2142  {
2143  return m_parameters;
2144  }
2145 
2151  void Serialize( IsoString& text, bool autoFormat, char indentChar, unsigned indentSize, unsigned level ) const override;
2152 
2153 private:
2154 
2155  String m_name;
2156  String m_parameters;
2157 };
2158 
2159 // ----------------------------------------------------------------------------
2160 
2171 class PCL_CLASS XMLDeclaration : public XMLComponent
2172 {
2173 public:
2174 
2179  XMLDeclaration( const String& version = String(), const String& encoding = String(), bool standalone = false ) :
2180  XMLComponent(),
2181  m_version( version ),
2182  m_encoding( encoding ),
2183  m_standalone( standalone )
2184  {
2185  }
2186 
2190  XMLDeclaration( const XMLDeclaration& ) = default;
2191 
2195  const String& Version() const
2196  {
2197  return m_version;
2198  }
2199 
2203  const String& DocumentEncoding() const
2204  {
2205  return m_encoding;
2206  }
2207 
2212  {
2213  return m_standalone;
2214  }
2215 
2221  bool IsDefined() const
2222  {
2223  return !m_version.IsEmpty();
2224  }
2225 
2235  void Serialize( IsoString& text ) const;
2236 
2237 private:
2238 
2239  String m_version;
2240  String m_encoding;
2241  bool m_standalone : 1;
2242 };
2243 
2244 // ----------------------------------------------------------------------------
2245 
2257 class PCL_CLASS XMLDocTypeDeclaration : public XMLComponent
2258 {
2259 public:
2260 
2265  XMLDocTypeDeclaration( const String& name = String(), const String& definition = String() ) :
2266  XMLComponent(),
2267  m_name( name ),
2268  m_definition( definition )
2269  {
2270  }
2271 
2275  XMLDocTypeDeclaration( const XMLDocTypeDeclaration& ) = default;
2276 
2280  const String& Name() const
2281  {
2282  return m_name;
2283  }
2284 
2288  const String& Definition() const
2289  {
2290  return m_definition;
2291  }
2292 
2298  bool IsDefined() const
2299  {
2300  return !m_name.IsEmpty();
2301  }
2302 
2310  void Serialize( IsoString& text ) const;
2311 
2312 private:
2313 
2314  String m_name;
2315  String m_definition;
2316 };
2317 
2318 // ----------------------------------------------------------------------------
2319 
2348 {
2353  {
2354  }
2355 
2360  virtual bool operator()( const XMLElement* parent, const String& name ) const = 0;
2361 
2372  virtual bool operator()( const XMLElement* parent, const String& name, const XMLAttributeList& attributes ) const
2373  {
2374  return true;
2375  }
2376 };
2377 
2378 // ----------------------------------------------------------------------------
2379 
2393 namespace XMLParserOption
2394 {
2395  enum mask_type
2396  {
2397  IgnoreComments = 0x00000001,
2398  IgnoreUnknownElements = 0x00000002,
2399  IgnoreStrayCharacters = 0x00000004,
2400  NormalizeTextSpaces = 0x00000008
2401  };
2402 }
2403 
2410 
2411 // ----------------------------------------------------------------------------
2412 
2493 class PCL_CLASS XMLDocument
2494 {
2495 public:
2496 
2500  typedef XMLNodeList::iterator iterator;
2501 
2505  typedef XMLNodeList::const_iterator const_iterator;
2506 
2511  typedef XMLParserOption::mask_type parser_option;
2512 
2524  {
2525  m_autoFormatting = false;
2526  m_indentTabs = false;
2527  m_indentSize = 3;
2528  }
2529 
2534  virtual ~XMLDocument()
2535  {
2536  m_nodes.Destroy();
2537  m_root = nullptr;
2538  RemoveElementFilter();
2539  }
2540 
2545  XMLDocument( const XMLDocument& ) = delete;
2546 
2551  XMLDocument& operator =( const XMLDocument& ) = delete;
2552 
2557  const XMLDeclaration& XML() const
2558  {
2559  return m_xml;
2560  }
2561 
2565  void SetXML( const XMLDeclaration& xml )
2566  {
2567  m_xml = xml;
2568  }
2569 
2574  void SetXML( const String& version = "1.0", const String& encoding = "UTF-8", bool standalone = false )
2575  {
2576  SetXML( XMLDeclaration( version, encoding, standalone ) );
2577  }
2578 
2584  {
2585  return m_docType;
2586  }
2587 
2592  void SetDocType( const XMLDocTypeDeclaration& docType )
2593  {
2594  m_docType = docType;
2595  }
2596 
2604  const XMLElement* RootElement() const
2605  {
2606  return m_root;
2607  }
2608 
2623  {
2624  XMLElement* root = m_root;
2625  m_nodes.RemovePointer( m_root );
2626  Clear();
2627  return root;
2628  }
2629 
2634  int NodeCount() const
2635  {
2636  return int( m_nodes.Length() );
2637  }
2638 
2643  bool IsEmpty() const
2644  {
2645  return m_nodes.IsEmpty();
2646  }
2647 
2653  const XMLNode& operator []( int i ) const
2654  {
2655  return m_nodes[i];
2656  }
2657 
2662  const_iterator Begin() const
2663  {
2664  return m_nodes.Begin();
2665  }
2666 
2671  const_iterator End() const
2672  {
2673  return m_nodes.End();
2674  }
2675 
2676 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
2677 
2680  const_iterator begin() const
2681  {
2682  return Begin();
2683  }
2684 
2688  const_iterator end() const
2689  {
2690  return End();
2691  }
2692 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
2693 
2708  void AddNode( XMLNode* node );
2709 
2716  {
2717  AddNode( node );
2718  return *this;
2719  }
2720 
2734  void SetRootElement( XMLElement* element );
2735 
2747  void Clear();
2748 
2759  {
2760  delete m_filter, m_filter = filter;
2761  }
2762 
2769  {
2770  SetElementFilter( nullptr );
2771  }
2772 
2778  void SetParserOption( parser_option option, bool on = true )
2779  {
2780  m_parserOptions.SetFlag( option, on );
2781  }
2782 
2788  void SetParserOptions( XMLParserOptions options )
2789  {
2790  m_parserOptions = options;
2791  }
2792 
2798  {
2799  m_parserOptions.Clear();
2800  }
2801 
2814  void Parse( const String& text );
2815 
2835  bool IsAutoFormatting() const
2836  {
2837  return m_autoFormatting;
2838  }
2839 
2844  void EnableAutoFormatting( bool enable = true )
2845  {
2846  m_autoFormatting = enable;
2847  }
2848 
2853  void DisableAutoFormatting( bool disable = true )
2854  {
2855  EnableAutoFormatting( !disable );
2856  }
2857 
2867  int IndentSize() const
2868  {
2869  return int( m_indentSize );
2870  }
2871 
2895  void SetIndentSize( int indentSize )
2896  {
2897  m_indentSize = unsigned( Range( indentSize, 0, 8 ) );
2898  }
2899 
2908  bool IsIndentTabs() const
2909  {
2910  return m_indentTabs;
2911  }
2912 
2917  void EnableIndentTabs( bool enable = true )
2918  {
2919  m_indentTabs = enable;
2920  }
2921 
2926  void DisableIndentTabs( bool disable = true )
2927  {
2928  EnableIndentTabs( !disable );
2929  }
2930 
2942  IsoString Serialize() const;
2943 
2953  void SerializeToFile( const String& path ) const;
2954 
2955 private:
2956 
2957  XMLDeclaration m_xml;
2958  XMLDocTypeDeclaration m_docType;
2959  XMLNodeList m_nodes;
2960  XMLElement* m_root = nullptr;
2961  XMLElementFilter* m_filter = nullptr;
2962  XMLParserOptions m_parserOptions;
2963  XMLNodeLocation m_location;
2964  bool m_autoFormatting : 1;
2965  bool m_indentTabs : 1;
2966  unsigned m_indentSize : 4;
2967 };
2968 
2969 // ----------------------------------------------------------------------------
2970 
2971 } // pcl
2972 
2973 #endif // __PCL_XML_h
2974 
2975 // ----------------------------------------------------------------------------
2976 // EOF pcl/XML.h - Released 2019-11-07T10:59:34Z
child_element_list ChildElements(bool recursive=false) const
Definition: XML.h:1572
bool IsChildNode() const
Definition: XML.h:540
XMLElement * ParentElement() const
Definition: XML.h:353
void SortAttributes(BP p)
Definition: XML.h:1378
Dynamic list of XML node objects.
bool IsElement() const
Definition: XML.h:557
XMLAttribute(const String &name, const String &value=String())
Definition: XML.h:744
const_iterator End() const
Definition: XML.h:1476
Abstract base class of all XML document node classes.
Definition: XML.h:498
void SetXML(const XMLDeclaration &xml)
Definition: XML.h:2565
Root base class of all XML document components.
Definition: XML.h:334
bool HasAttribute(const String &name) const
Definition: XML.h:948
void ParseAttributes(const String &text)
Definition: XML.h:1394
static bool IsWhiteSpaceChar(T c)
Definition: XML.h:117
bool IsEmpty() const
Definition: XML.h:1428
const XMLNodeLocation & Location() const
Definition: XML.h:583
const_iterator Begin() const
Definition: XML.h:2662
const String & Instructions() const
Definition: XML.h:2023
node_type NodeType() const
Definition: XML.h:548
XMLNodeType::mask_type node_type
Definition: XML.h:506
int ChildCount() const
Definition: XML.h:1419
void SetAttributes(const XMLAttributeList &list)
Definition: XML.h:1327
A functional class for filtering XML elements.
Definition: XML.h:2347
const String & Name() const
Definition: XML.h:759
XMLNode(node_type type)
Definition: XML.h:513
XML DOCTYPE declaration
Definition: XML.h:2257
XML element attribute
Definition: XML.h:721
const String & Value() const
Definition: XML.h:767
Array< XMLAttribute > list_implementation
Definition: XML.h:844
void SetValue(const String &text)
Definition: XML.h:775
XMLComment(const String &comment)
Definition: XML.h:2065
PCL root namespace.
Definition: AbstractImage.h:76
static bool IsNameStartChar(T c)
Definition: XML.h:149
XMLAttributeList Attributes() const
Definition: XML.h:1235
String AsString(mask_type type)
XML comment section
Definition: XML.h:2053
child_element_list ChildElementsByName(const String &name, bool recursive=false) const
Definition: XML.h:1605
const String & Name() const
Definition: XML.h:1227
XML declaration
Definition: XML.h:2171
ReferenceArray< XMLElement > child_element_list
Definition: XML.h:1154
string_base::const_iterator const_iterator
Definition: String.h:7969
XML parsing error with automatic text location information generation
Definition: XML.h:656
iterator End()
Definition: String.h:973
XMLParserOption::mask_type parser_option
Definition: XML.h:2511
int Length() const
Definition: XML.h:885
String EncodedValue() const
Definition: XML.h:785
bool IsEmpty() const
Definition: String.h:785
static bool IsValidName(const String &name)
Definition: XML.h:207
String EncodedText() const
Definition: XML.h:1868
A collection of XML node types.
static String ReferenceValue(const String &reference)
Definition: XML.h:316
virtual ~XMLElement()
Definition: XML.h:1204
int NodeCount() const
Definition: XML.h:2634
XMLText(const String &text, bool preserveSpaces=true)
Definition: XML.h:1833
bool IsDefined() const
Definition: XML.h:2298
const_iterator begin() const
Definition: XML.h:1485
bool HasComments() const
Definition: XML.h:1536
XMLAttributeList(const String &text)
Definition: XML.h:867
void RemoveAttribute(const String &name)
Definition: XML.h:1349
const_iterator Begin() const
Definition: XML.h:1467
String SpaceTransformedText(bool collapse, bool trim) const
Definition: XML.h:1881
const String & Target() const
Definition: XML.h:2015
Utility functions and data for XML document parsing and generation.
Definition: XML.h:84
void SetAttributes(const XMLAttributeList &list)
Definition: XML.h:1034
XML document parsing and generation
Definition: XML.h:2493
XMLUnknownElement(const String &name, const String &parameters=String())
Definition: XML.h:2118
void EnableIndentTabs(bool enable=true)
Definition: XML.h:2917
const String & DocumentEncoding() const
Definition: XML.h:2203
Array< T, A > & operator<<(Array< T, A > &x, const V &v)
Definition: Array.h:2103
XMLNodeList ChildNodesThat(UP u, bool recursive=false) const
Definition: XML.h:1671
void EnableAutoFormatting(bool enable=true)
Definition: XML.h:2844
bool IsEmpty() const
Definition: XML.h:2643
XMLDocTypeDeclaration(const String &name=String(), const String &definition=String())
Definition: XML.h:2265
static bool IsNameChar(T c)
Definition: XML.h:175
XML text block
Definition: XML.h:1812
list_implementation::iterator iterator
Definition: XML.h:849
XMLProcessingInstructions(const String &target, const String &instructions)
Definition: XML.h:2000
constexpr const T & Range(const T &x, const T &a, const T &b)
Definition: Utility.h:190
void SetElementFilter(XMLElementFilter *filter)
Definition: XML.h:2758
static bool IsSpaceChar(T c)
Definition: XML.h:138
const String & Comment() const
Definition: XML.h:2079
XMLNode(const XMLNode &x)
Definition: XML.h:525
void ClearParserOptions()
Definition: XML.h:2797
bool IsStandaloneDocument() const
Definition: XML.h:2211
void SetAttribute(const XMLAttribute &attribute)
Definition: XML.h:1294
XMLElement(XMLElement &parent, const String &name, const XMLAttributeList &attributes=XMLAttributeList())
Definition: XML.h:1180
void SerializeAttributes(IsoString &text) const
Definition: XML.h:1411
int IndentSize() const
Definition: XML.h:2867
void SetXML(const String &version="1.0", const String &encoding="UTF-8", bool standalone=false)
Definition: XML.h:2574
XMLNodeList ChildNodesByType(XMLNodeTypes types, bool recursive=false) const
Definition: XML.h:1636
static bool IsRestrictedChar(T c)
Definition: XML.h:192
bool IsEmpty() const
Definition: XML.h:893
Unicode (UTF-16) string.
Definition: String.h:7911
bool NLAfter(const XMLNode &previous) const override
Definition: XML.h:1909
const String & Name() const
Definition: XML.h:2280
void ClearAttributes()
Definition: XML.h:1357
XMLNodeList::const_iterator const_iterator
Definition: XML.h:2505
static String CollapsedSpaces(String::const_iterator i, String::const_iterator j)
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:1219
const String & CData() const
Definition: XML.h:1958
void SetParserOption(parser_option option, bool on=true)
Definition: XML.h:2778
virtual ~XMLElementFilter()
Definition: XML.h:2352
void DisableIndentTabs(bool disable=true)
Definition: XML.h:2926
const_iterator begin() const
Definition: XML.h:930
bool HasText() const
Definition: XML.h:1510
bool IsTopLevel() const
Definition: XML.h:362
XMLNodeList ReleaseChildNodes()
Definition: XML.h:1761
const_iterator Begin() const
Definition: XML.h:912
bool IsText() const
Definition: XML.h:566
XMLParseError(const XMLNode &node, const String &whileDoing, const String &whatHappened)
Definition: XML.h:676
virtual ~XMLDocument()
Definition: XML.h:2534
void DisableAutoFormatting(bool disable=true)
Definition: XML.h:2853
void SortAttributes()
Definition: XML.h:1366
bool IsAutoFormatting() const
Definition: XML.h:2835
bool HasAttributes() const
Definition: XML.h:1243
bool IsDefined() const
Definition: XML.h:2221
void RemoveElementFilter()
Definition: XML.h:2768
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2)
Definition: Array.h:2086
bool HasElements() const
Definition: XML.h:1502
void RemoveAttribute(const String &name)
Definition: XML.h:1056
void SetIndentSize(int indentSize)
Definition: XML.h:2895
String AttributeValue(const String &name) const
Definition: XML.h:958
A simple exception with an associated error message.
Definition: Exception.h:213
const_iterator end() const
Definition: XML.h:2688
void AddChildNodes(XMLNodeList &nodes)
Definition: XML.h:1711
XML element
Definition: XML.h:1136
const_iterator end() const
Definition: XML.h:1493
void SetAttribute(const String &name, const String &value)
Definition: XML.h:979
const String & Text() const
Definition: XML.h:1849
XMLElement(const String &name, const XMLAttributeList &attributes=XMLAttributeList())
Definition: XML.h:1168
void AddChildNode(XMLNode *node)
Definition: XML.h:1684
list_implementation::const_iterator const_iterator
Definition: XML.h:854
void DestroyChildNodes()
Definition: XML.h:1746
bool HasProcessingInstructions() const
Definition: XML.h:1527
const_iterator begin() const
Definition: XML.h:2680
XMLParseError(const XMLNodeLocation &where, const String &whileDoing, const String &whatHappened)
Definition: XML.h:697
FlagType< std::is_unsigned< enum_type >::value >::type flag_type
Definition: Flags.h:100
void SetDocType(const XMLDocTypeDeclaration &docType)
Definition: XML.h:2592
virtual bool operator()(const XMLElement *parent, const String &name, const XMLAttributeList &attributes) const
Definition: XML.h:2372
XMLCDATA(const String &data)
Definition: XML.h:1943
static bool IsLineBreakChar(T c)
Definition: XML.h:127
XML processing instructions
Definition: XML.h:1988
Dynamic list of XML element attributes.
Definition: XML.h:836
const XMLNode & Last() const
Definition: XML.h:1458
bool IsIndentTabs() const
Definition: XML.h:2908
void SetAttribute(const XMLAttribute &attribute)
Definition: XML.h:996
bool IsComment() const
Definition: XML.h:575
XMLElement * ReleaseRootElement()
Definition: XML.h:2622
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2)
Definition: Array.h:2075
A collection of XML document parsing options.
XMLNodeList::iterator iterator
Definition: XML.h:2500
XMLDeclaration(const String &version=String(), const String &encoding=String(), bool standalone=false)
Definition: XML.h:2179
const XMLNode & First() const
Definition: XML.h:1448
const XMLDocTypeDeclaration & DocType() const
Definition: XML.h:2583
XMLNodeLocation(int line_, int column_)
Definition: XML.h:460
const String & Definition() const
Definition: XML.h:2288
const_iterator End() const
Definition: XML.h:2671
String AttributeValue(const String &name) const
Definition: XML.h:1262
const_iterator End() const
Definition: XML.h:921
static String TrimmedSpaces(String::const_iterator i, String::const_iterator j)
const XMLDeclaration & XML() const
Definition: XML.h:2557
const String & Name() const
Definition: XML.h:2133
const XMLElement * RootElement() const
Definition: XML.h:2604
const String & Parameters() const
Definition: XML.h:2141
void SetAttribute(const String &name, const String &value)
Definition: XML.h:1282
XML CDATA section
Definition: XML.h:1932
XMLNodeList::const_iterator const_iterator
Definition: XML.h:1148
bool IsPreserveSpaces() const
Definition: XML.h:1858
const String & Version() const
Definition: XML.h:2195
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:1252
iterator Begin()
Definition: String.h:943
virtual ~XMLNode()
Definition: XML.h:533
const_iterator end() const
Definition: XML.h:938
void SetParserOptions(XMLParserOptions options)
Definition: XML.h:2788
Unsupported or invalid XML element.
Definition: XML.h:2110
XMLNodeList::iterator iterator
Definition: XML.h:1143
bool HasCDATA() const
Definition: XML.h:1518
Eight-bit string (ISO/IEC-8859-1 or UTF-8 string)
Definition: String.h:5387