driver.cxx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // file : examples/processing/driver.cxx
  2. // copyright : not copyrighted - public domain
  3. #include <string>
  4. #include <fstream>
  5. #include <iostream>
  6. #include <xml/parser>
  7. #include <xml/serializer>
  8. #include <xml/value-traits>
  9. using namespace std;
  10. using namespace xml;
  11. enum object_type {building, mountain};
  12. // Specialization of xml::value_traits for object_type. This mechanism is
  13. // used to implements XML-specific value type parsing and serialization.
  14. // By default the parser and serializer fall back onto iostream insertion
  15. // and extraction operators.
  16. //
  17. // This code also shows how we can reuse the parsing exception to implement
  18. // our own diagnostics.
  19. //
  20. namespace xml
  21. {
  22. template <>
  23. struct value_traits<object_type>
  24. {
  25. static object_type
  26. parse (string s, const parser& p)
  27. {
  28. if (s == "building")
  29. return building;
  30. else if (s == "mountain")
  31. return mountain;
  32. else
  33. throw parsing (p, "invalid object type '" + s + "'");
  34. }
  35. static string
  36. serialize (object_type x, const serializer&)
  37. {
  38. if (x == building)
  39. return "building";
  40. else
  41. return "mountain";
  42. }
  43. };
  44. }
  45. int
  46. main (int argc, char* argv[])
  47. {
  48. if (argc != 2)
  49. {
  50. cerr << "usage: " << argv[0] << " <xml-file>" << endl;
  51. return 1;
  52. }
  53. try
  54. {
  55. // Parse the input document and compute the average object position.
  56. //
  57. ifstream ifs (argv[1]);
  58. parser p (ifs, argv[1]);
  59. p.next_expect (parser::start_element, "object", content::complex);
  60. unsigned int id (p.attribute<unsigned int> ("id"));
  61. string name (p.element ("name"));
  62. object_type type (p.element<object_type> ("type"));
  63. float alat (0), alon (0);
  64. unsigned int count (0);
  65. do
  66. {
  67. p.next_expect (parser::start_element, "position", content::empty);
  68. float lat (p.attribute<float> ("lat"));
  69. float lon (p.attribute<float> ("lon"));
  70. p.next_expect (parser::end_element); // position
  71. alat += lat;
  72. alon += lon;
  73. count++;
  74. } while (p.peek () == parser::start_element);
  75. // Here is another example of re-using the parsing exception to
  76. // implement application-level diagnostics. Every object in our
  77. // vocabulary should have at least two position samples.
  78. //
  79. if (count < 2)
  80. throw parsing (p, "at least two position samples required");
  81. alat /= count;
  82. alon /= count;
  83. p.next_expect (parser::end_element); // object
  84. // Serialize an XML document with simulated positions based on the
  85. // average we just calculated.
  86. //
  87. serializer s (cout, "output");
  88. s.start_element ("object");
  89. s.attribute ("id", id);
  90. s.element ("name", name);
  91. s.element ("type", type);
  92. for (unsigned int i (0); i < 2; ++i)
  93. {
  94. for (unsigned int j (0); j < 2; ++j)
  95. {
  96. s.start_element ("position");
  97. float lat (alat + (i % 2 ? 0.0001F : -0.0001F));
  98. float lon (alon + (j % 2 ? -0.0001F : 0.0001F));
  99. s.attribute ("lat", lat);
  100. s.attribute ("lon", lon);
  101. s.end_element (); // position
  102. }
  103. }
  104. s.end_element (); // object
  105. }
  106. // This handler will handle both parsing (xml::parsing) and serialization
  107. // (xml::serialization) exceptions.
  108. //
  109. catch (const xml::exception& e)
  110. {
  111. cerr << e.what () << endl;
  112. return 1;
  113. }
  114. }