summaryrefslogtreecommitdiff
path: root/examples/cxx/tree/order/element/driver.cxx
blob: 0ea6d6f10efce8ed2fee9cab533fb2e88cfead0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// file      : examples/cxx/tree/order/element/driver.cxx
// copyright : not copyrighted - public domain

#include <memory>   // std::auto_ptr
#include <cassert>
#include <iostream>

#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/PlatformUtils.hpp>

#include "transactions.hxx"

// The following string class keeps us sane when working with Xerces.
// Include it after the generated header in order to get only char or
// wchar_t version depending on how you compiled your schemas.
//
#include <xsd/cxx/xml/string.hxx>

using std::cerr;
using std::endl;

int
main (int argc, char* argv[])
{
  if (argc != 2)
  {
    cerr << "usage: " << argv[0] << " transactions.xml" << endl;
    return 1;
  }

  using namespace xercesc;

  int r (0);

  // The Xerces-C++ DOM objects that will be used to store the
  // content matched by the wildcard "out-lives" the call to the
  // parsing function. Therefore we need to initialize the
  // Xerces-C++ runtime ourselves.
  //
  XMLPlatformUtils::Initialize ();

  try
  {
    using namespace transactions;

    // Parse the batch.
    //
    std::auto_ptr<batch> b (
      batch_ (argv[1], xml_schema::flags::dont_initialize));

    // Print what we've got in content order.
    //
    for (batch::content_order_const_iterator i (b->content_order ().begin ());
         i != b->content_order ().end ();
         ++i)
    {
      switch (i->id)
      {
      case batch::balance_id:
        {
          const balance& t (b->balance ()[i->index]);
          cerr << t.account () << " balance" << endl;
          break;
        }
      case batch::withdraw_id:
        {
          const withdraw& t (b->withdraw ()[i->index]);
          cerr << t.account () << " withdraw " << t.amount () << endl;
          break;
        }
      case batch::deposit_id:
        {
          const deposit& t (b->deposit ()[i->index]);
          cerr << t.account () << " deposit " << t.amount () << endl;
          break;
        }
      case batch::any_id:
        {
          namespace xml = xsd::cxx::xml;

          const DOMElement& e (b->any ()[i->index]);
          cerr << xml::transcode<char> (e.getLocalName ()) << endl;
          break;
        }
      default:
        {
          assert (false); // Unknown content id.
        }
      }
    }

    cerr << endl;

    // Modify the transaction batch. First remove the last transaction.
    // Note that we have to update both the content itself and content
    // order sequences.
    //
    batch::content_order_sequence& co (b->content_order ());

    co.pop_back ();
    b->withdraw ().pop_back ();

    // Now add a few more transactions. Again we have to add both the
    // content and its ordering. The order information consists of the
    // content id and, in case of a sequence, the index.
    //
    b->deposit ().push_back (deposit (123456789, 100000));
    co.push_back (
      batch::content_order_type (
        batch::deposit_id, b->deposit ().size () - 1));

    // The next transaction we add at the beginning of the batch.
    //
    b->balance ().push_back (balance (123456789));
    co.insert (co.begin (),
               batch::content_order_type (
                 batch::balance_id, b->balance ().size () - 1));

    // Note also that when we merely modify the content of one
    // of the elements in place, we don't need to update its
    // order. For example:
    //
    b->deposit ()[0].amount (2000000);

    // Serialize the modified transaction batch back to XML.
    //
    xml_schema::namespace_infomap map;

    map[""].name = "http://www.codesynthesis.com/transactions";
    map[""].schema = "transactions.xsd";
    map["te"].name = "http://www.codesynthesis.com/transactions-extras";

    batch_ (std::cout,
            *b,
            map,
            "UTF-8",
            xml_schema::flags::dont_initialize);
  }
  catch (const xml_schema::exception& e)
  {
    cerr << e << endl;
    r = 1;
  }

  XMLPlatformUtils::Terminate ();
  return r;
}