1
0

tiny_xml.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // tiny XML sub-set tools implementation -----------------------------------//
  2. // (C) Copyright Beman Dawes 2002. Permission to copy,
  3. // use, modify, sell and distribute this software is granted provided this
  4. // copyright notice appears in all copies. This software is provided "as is"
  5. // without express or implied warranty, and with no claim as to its
  6. // suitability for any purpose.
  7. #include "tiny_xml.hpp"
  8. #include <cassert>
  9. namespace
  10. {
  11. void eat_whitespace( char & c, std::istream & in )
  12. {
  13. while ( c == ' ' || c == '\r' || c == '\n' || c == '\t' )
  14. in.get( c );
  15. }
  16. std::string get_name( char & c, std::istream & in )
  17. {
  18. std::string result;
  19. eat_whitespace( c, in );
  20. while ( std::strchr(
  21. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.", c )
  22. != 0 )
  23. {
  24. result += c;
  25. in.get( c );
  26. }
  27. return result;
  28. }
  29. void eat_delim( char & c, std::istream & in, char delim )
  30. {
  31. eat_whitespace( c, in );
  32. if ( c != delim )
  33. throw (std::string("xml syntax error, expected ") + delim);
  34. in.get( c );
  35. }
  36. std::string get_value( char & c, std::istream & in )
  37. {
  38. std::string result;
  39. while ( c != '\"' )
  40. {
  41. result += c;
  42. in.get( c );
  43. }
  44. in.get( c );
  45. return result;
  46. }
  47. }
  48. namespace boost
  49. {
  50. namespace tiny_xml
  51. {
  52. // parse -----------------------------------------------------------------//
  53. element_ptr parse( std::istream & in )
  54. {
  55. char c = 0; // current character
  56. element_ptr e( new element );
  57. in.get( c );
  58. if ( c == '<' ) in.get( c );
  59. e->name = get_name( c, in );
  60. eat_whitespace( c, in );
  61. // attributes
  62. while ( c != '>' )
  63. {
  64. attribute a;
  65. a.name = get_name( c, in );
  66. eat_delim( c, in, '=' );
  67. eat_delim( c, in, '\"' );
  68. a.value = get_value( c, in );
  69. e->attributes.push_back( a );
  70. eat_whitespace( c, in );
  71. }
  72. in.get( c ); // next after '>'
  73. eat_whitespace( c, in );
  74. // sub-elements
  75. while ( c == '<' )
  76. {
  77. if ( in.peek() == '/' ) break;
  78. e->elements.push_back( parse( in ) );
  79. in.get( c ); // next after '>'
  80. eat_whitespace( c, in );
  81. }
  82. // content
  83. if ( c != '<' )
  84. {
  85. e->content += '\n';
  86. while ( c != '<' )
  87. {
  88. e->content += c;
  89. in.get( c );
  90. }
  91. }
  92. assert( c == '<' );
  93. in.get( c ); // next after '<'
  94. eat_delim( c, in, '/' );
  95. std::string end_name( get_name( c, in ) );
  96. if ( e->name != end_name )
  97. throw (std::string("xml syntax error: beginning name ") +
  98. e->name + " did not match end name " + end_name);
  99. eat_delim( c, in, '>' );
  100. return e;
  101. }
  102. // write ---------------------------------------------------------------//
  103. void write( const element & e, std::ostream & out )
  104. {
  105. out << "<" << e.name;
  106. if ( !e.attributes.empty() )
  107. {
  108. for( attribute_list::const_iterator itr = e.attributes.begin();
  109. itr != e.attributes.end(); ++itr )
  110. {
  111. out << " " << itr->name << "=\"" << itr->value << "\"";
  112. }
  113. }
  114. out << ">";
  115. if ( !e.elements.empty() )
  116. {
  117. out << "\n";
  118. for( element_list::const_iterator itr = e.elements.begin();
  119. itr != e.elements.end(); ++itr )
  120. {
  121. write( **itr, out );
  122. }
  123. }
  124. if ( !e.content.empty() )
  125. {
  126. out << e.content;
  127. }
  128. out << "</" << e.name << ">\n";
  129. }
  130. } // namespace tiny_xml
  131. } // namespace boost
粤ICP备19079148号