summaryrefslogtreecommitdiffstats
path: root/xdocs/docs/om_tutorial.html
diff options
context:
space:
mode:
authorGravatar gmcdonald2010-02-13 01:32:03 +0000
committerGravatar gmcdonald2010-02-13 01:32:03 +0000
commit0425aadc78680e53000fd0108b540d6eca048516 (patch)
tree8ec7ab8e015d454c5ec586dfc91e05a2dce1cfc0 /xdocs/docs/om_tutorial.html
downloadaxis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.gz
axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.bz2
Moving axis svn, part of TLP move INFRA-2441
git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'xdocs/docs/om_tutorial.html')
-rw-r--r--xdocs/docs/om_tutorial.html547
1 files changed, 547 insertions, 0 deletions
diff --git a/xdocs/docs/om_tutorial.html b/xdocs/docs/om_tutorial.html
new file mode 100644
index 0000000..70eb038
--- /dev/null
+++ b/xdocs/docs/om_tutorial.html
@@ -0,0 +1,547 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head><title>Apache Axis2/C - AXOM Tutorial</title><h2>Apache Axis2/C AXIOM Tutorial</h2><div class="subsection"><a name="Contents"></a><h3>Contents</h3><ul>
+ <li><a href="#Introduction">Introduction</a>
+ <ul>
+ <li><a href="#What_is_OM">What is AXIOM?</a></li>
+ <li><a href="#For_Whom_is_This_Tutorial">For whom is this
+ tutorial?</a></li>
+ <li><a href="#What_is_Pull_Parsing">What is Pull Parsing?</a></li>
+ <li><a href="#Features_of_OM">Features of AXIOM</a></li>
+ <li><a href="#Where_Does_SOAP_Come_into_Play">Where does SOAP come into
+ play?</a></li>
+ </ul>
+ </li>
+ <li><a href="#Working_with_OM">Working with AXIOM</a>
+ <ul>
+ <li><a href="#Env">Axis2/C Environment</a></li>
+ <li><a href="#Creation">Building AXIOM</a></li>
+ <li><a href="#Addition_and_Detaching_of_Nodes">Adding and Detaching
+ Nodes</a></li>
+ <li><a href="#Traversing">Traversing</a></li>
+ <li><a href="#Serialization">Serialization</a></li>
+ <li><a href="#Reader_and_Writer">Using axiom_xml_reader and
+ axiom_xml_writer</a></li>
+ <li><a href="#Mem_Leaks">How to avoid memory leaks and double frees
+ when using AXIOM</a></li>
+ <li><a href="#Complete_Sample">Complete Sample</a></li>
+ </ul>
+ </li>
+</ul><p><a id="Introduction"></a></p></div><div class="subsection"><a name="Introduction"></a><h3>Introduction</h3><p><a id="What_is_OM"></a></p></div><div class="subsection"><a name="What_is_AXIOM_"></a><h3>What is AXIOM?</h3><p>AXIOM stands for AXis Object Model and refers to the XML infoset model
+that is developed for Apache Axis2. XML infoset refers to the information
+included inside the XML. For programmatical manipulation, it is convenient to
+have a representation of this XML infoset in a language specific manner. DOM
+and JDOM are two such XML models. AXIOM is conceptually similar to such an
+XML model in its external behavior but deep down it is very different.</p><p>The objective of this tutorial is to introduce the basics of AXIOM/C and
+explain the best practices while using AXIOM.</p><p>AXIOM/C is a C equivalant of AXIOM/Java. We have done our best to get
+almost the same kind of API in C.</p><p><a id="For_Whom_is_This_Tutorial"></a></p></div><div class="subsection"><a name="For_whom_is_this_tutorial_"></a><h3>For whom is this tutorial?</h3><p>This tutorial can be used by anybody who is interested and wants to go
+deeper in to AXIOM/C. Knowledge in similar object models such as DOM will be
+helpful in understanding AXIOM, but such knowledge has not been assumed.
+Several links are listed in the links section that will help you understand
+the basics of XML.</p><p><a id="What_is_Pull_Parsing"></a></p></div><div class="subsection"><a name="What_is_Pull_Parsing__"></a><h3>What is Pull Parsing ?</h3><p>
+Pull parsing is a new trend in XML processing. The previously popular XML
+processing frameworks such as DOM were "push-based", which means that the
+control of parsing was with the parser itself. This approach is fine and easy
+to use, but it is not efficient in handling large XML documents since a
+complete memory model will be generated in the memory. Pull parsing inverts
+the control and hence the parser only proceeds at the user's command. The
+user can decide to store or discard events generated from the parser. AXIOM
+is based on pull parsing. To learn more about XML pull parsing, see the <a href="http://www.bearcave.com/software/java/xml/xmlpull.html" class="externalLink" title="External Link">XML pull
+parsing introduction</a>. <a id="Features_of_OM"></a></p></div><div class="subsection"><a name="Features_of_AXIOM"></a><h3>Features of AXIOM</h3><p>AXIOM is a lightweight, differed built XML infoset representation based on
+StAX API derived from <a href="http://www.jcp.org/aboutJava/communityprocess/first/jsr173/" class="externalLink" title="External Link">JSR
+173</a>, which is the standard streaming pull parser API. AXIOM can be
+manipulated as flexibly as any other object model such as <a href="http://www.jdom.org/" class="externalLink" title="External Link">JDOM</a>, but underneath, the objects will be
+created only when they are absolutely required. This leads to much less
+memory-intensive programming.</p><p>The following is a short feature overview of AXIOM.</p><ul>
+ <li>Lightweight: AXIOM is specifically targeted to be lightweight. This is
+ achieved by reducing the depth of the hierarchy, the number of methods,
+ and the attributes enclosed in the objects. This makes the objects less
+ memory intensive.</li>
+ <li>Differed building: By far, this is the most important feature of AXIOM.
+ The objects are not made unless a need arises for them. This passes the
+ control of building to the object model itself, rather than an external
+ builder.</li>
+ <li>Pull based: For a differed building mechanism, a pull-based parser is
+ required. AXIOM is based on StAX, which is the standard pull parser API.
+ <p>Since different XML parsers offer different kinds of pull parser APIs,
+ we define an API derived from StAX. That API is defined in
+ <code>axiom_xml_reader.h</code>. Similarly, we define an XML writer API
+ in <code>axiom_xml_writer.h</code>. These two APIs work as an abstarction
+ layer between any XML parser and AXIOM. So any parser that is going to be
+ used for AXIOM should implement the <code>axiom_xml_reader</code> API and
+ the <code>axiom_xml_writer</code> API using a wrapper layer.</p>
+ <p></p>
+ <p>Currenly we use <a href="http://xmlsoft.org/downloads.html" class="externalLink" title="External Link">Libxml2</a> as our default XML
+ parser.</p>
+ <p></p>
+ </li>
+</ul><p class="img"><img alt="" src="images/archi006.jpg" class="img" width="490" height="282"></img></p><p>The AXIOM Builder wraps the raw XML character stream through the
+<code>axiom_xml_reader</code> API. Hence the complexities of the pull event
+stream are hidden from the user.</p><p><a id="Where_Does_SOAP_Come_into_Play"></a></p></div><div class="subsection"><a name="Where_does_SOAP_come_into_play_"></a><h3>Where does SOAP come into play?</h3><p>In a nutshell, SOAP is an information exchange protocol based on XML. SOAP
+has a defined set of XML elements that should be used in messages. Since
+Axis2 is a "SOAP Engine" and AXIOM is designed for Axis2, a SOAP specific API
+was implemented on top of AXIOM. We have defined a number of structs to
+represent SOAP constructs, which wrap general AXIOM structures. Learn more
+about <a href="http://www.w3schools.com/SOAP/soap_intro.asp" class="externalLink" title="External Link">SOAP</a>.</p><p>
+<a id="Working_with_OM"></a></p></div><div class="subsection"><a name="Working_with_AXIOM"></a><h3>Working with AXIOM</h3><p><a id="Env"></a></p></div><div class="subsection"><a name="Axis2_C_Environment"></a><h3>Axis2/C Environment</h3><p>Before starting the discussion on AXIOM, it is necessary to get a good
+understanding of the basics of Axis2/C. Axis2/C is designed to be pluggable
+to any system written in C or C++. Therefore, Axis2/C has abstracted the
+functionalities that differ from system to system into a structure
+<code>axutil_env_t</code>, which we refer to as the Axis2 environment. The
+environment holds <code>axutil_allocator_t</code>, which is used for memory
+allocation and deallocation, <code>axutil_error_t</code>, which is used for
+error reporting, <code>axutil_log_t</code>, which is used for logging
+mechanisms, and <code>axutil_thread_t</code> which is used for threading
+mechanisms.</p><p>When creating the Axis2 environment, the first thing is to create the
+allocator.</p><p><code>axutil_allocator_t *allocator = NULL;</code></p><p><code>allocator = axutil_allocator_init(NULL);</code></p><p>We pass <code>NULL</code> to the above function in order to use the
+default allocator functions. Then the allocator functions will use the
+<code>malloc</code>, and <code>free</code> functions for memory management.
+If you have your own allocator structure, with custom malloc and free
+functions, you can pass them instead.</p><p>Convenient macros <code>AXIS2_MALLOC</code> and <code>AXIS2_FREE</code>
+are defined to use allocator functions (please have a look at
+<code>axutil_allocator.h</code> for more information).</p><p>In a similar fashion, you can create the error and log structures.</p><p><code>axutil_log_t *log = NULL;</code></p><p><code>axutil_error_t *error = NULL;</code></p><p><code>log = axutil_log_create(allocator, NULL, NULL);</code></p><p><code>log = axutil_log_create(allocator, NULL, "mylog.log");</code></p><p></p><p>Now we can create the environment by parsing the allocator, error and log
+to <code>axutil_env_create_with_error_log()</code> function.</p><p><code>axutil_env_t *env = NULL;</code></p><p><code>env = axutil_env_create_with_error_log(allocator, error,
+log);</code></p><p>Apart from the above abstraction, all the other library functions used are
+ANSI C compliant. Further, platform dependent functions are also
+abstracted.</p><p>As a rule of thumb, all <code>create</code> functions take a pointer to
+the environment as its first argument, and all the other functions take
+pointer to this particular struct as the first argument, and a pointer to the
+environment as the second argument. (Please refer to our <a href="../coding_conventions.html">coding convention page</a> to learn more
+about this.)</p><p>Example,</p><p><code>axiom_node_t *node = NULL;</code></p><p><code>axiom_node_t *child = NULL;</code></p><p><code>node = axiom_node_create(env);</code></p><p><code>child = axiom_node_get_first_child(node, env);</code></p><p>Note that we are passing the node (pointer to <code>axiom_node_t</code> )
+as the first argument and the pointer to the environment as the second.</p><p><a id="Creation"></a></p></div><div class="subsection"><a name="Building_AXIOM"></a><h3>Building AXIOM</h3><p>This section explains how AXIOM can be built either from an existing
+document or programmatically. AXIOM provides a notion of a builder to create
+objects. Since AXIOM is tightly bound to StAX, a StAX compliant reader should
+be created first with the desired input stream.</p><p>In our AXIOM implementation, we define a struct <code>axiom_node_t</code>
+which acts as the container of the other structs. <code>axiom_node_t</code>
+maintains the links that form the linked list used to hold the AXIOM
+structure.</p><p>To traverse this structure, the functions defined in
+<code>axiom_node.h</code> must be used. To access XML information, the 'data
+element' struct stored in <code>axiom_node_t</code> must be obtained using
+the <code>axiom_node_get_data_element</code> function. The type of the struct
+stored in the <code>axiom_node_t</code> struct can be obtained by the
+<code>axiom_node_get_node_type</code> function. When we create
+<code>axiom_element_t</code>, <code>axiom_text_t</code> etc., it is required
+to parse a double pointer to the node struct as the last parameter of the
+<code>create</code> function, so that the corresponding node struct can be
+referenced using that pointer.</p><p>Example</p><p><code>axiom_node_t *my_node = NULL;</code></p><p><code>axiom_element_t *my_ele = NULL;</code></p><p><code>my_ele = axiom_element_create(env, NULL, "MY_ELEMENT", NULL,
+&amp;my_node);</code></p><p></p><p>Now if we call the <code>axiom_node_get_node_type</code> function on the
+<code>my_node</code> pointer, it will return <code>AXIOM_ELEMENT</code>.</p><p><b>Code Listing 1</b></p>
+ <div class="source"><pre>axiom_xml_reader_t *xml_reader = NULL;
+axiom_stax_builder_t *om_builder = NULL;
+axiom_soap_builder_t *soap_builder = NULL;
+axiom_soap_envelope_t *soap_envelope = NULL;
+
+xml_reader = axiom_xml_reader_create_for_file(env, "test_soap.xml", NULL);
+
+om_builder = axiom_stax_builder_create(env, xml_reader);
+
+soap_builder = axiom_soap_builder_create(env, om_builder , AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI);
+
+soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
+
+</pre></div>
+ <p>As the example shows, creating an AXIOM from <code>xml_reader</code> is
+pretty straight forward. Elements and nodes can be created programmatically
+to modify the structure as well. Currently AXIOM has two builders, namely the
+<code>axiom_stax_builder_t</code> and the <code>axiom_soap_builder_t</code>.
+These builders provide the necessary information to the XML infoset model to
+build the AXIOM tree.</p><p><b>Code Listing 2</b></p>
+ <div class="source"><pre>axiom_namespace_t *ns1 = NULL;
+axiom_namespace_t *ns2 = NULL;
+
+axiom_element_t* root_ele = NULL;
+axiom_node_t* root_ele_node = NULL;
+
+axiom_element_t *ele1 = NULL;
+axiom_node_t *ele1_node = NULL;
+
+ns1 = axiom_namespace_create(env, "bar", "x");
+ns2 = axiom_namespace_create(env, "bar1", "y");
+
+root_ele = axiom_element_create(env, NULL, "root", ns1, &amp;root_ele_node);
+ele1 = axiom_element_create(env, root_node, "foo1", ns2, &amp;ele1_node);
+
+</pre></div>
+ <p>Several differences exist between a programmatically created
+<code>axiom_node_t</code> and a conventionally built
+<code>axiom_node_t</code>. The most important difference is that the latter
+will have a pointer to its builder, where as the former does not have a
+builder.</p><p>The SOAP struct hierarchy is made in the most natural way for a
+programmer. It acts as a wrapper layer on top of the AXIOM implementation.
+The SOAP structs wrap the corresponding <code>axiom_node_t</code> structs to
+store XML information.</p><p><a id="Addition_and_Detaching_of_Nodes"></a></p></div><div class="subsection"><a name="Adding_and_Detaching_Nodes"></a><h3>Adding and Detaching Nodes</h3><p>Addition and removal methods are defined in the <code>axiom_node.h</code>
+header file.</p><p><b>Code Listing 3</b></p><p>Add child operation</p>
+ <div class="source"><pre>axis2_status_t
+axiom_node_add_child(axiom_node_t *om_node,
+ const axutil_env_t *env,
+ axiom_node_t *child_node);
+
+</pre></div>
+ <p>Detach operation</p>
+ <div class="source"><pre>axiom_node_t *
+axiom_node_detach(axiom_node_t *om_node,
+ const axutil_env_t *env);
+
+</pre></div>
+ <p>The detach operation resets the links and removes a node from the AXIOM
+tree.</p><p>This code segment shows how child addition can be done.</p><p><b>Code Listing 4</b></p>
+ <div class="source"><pre>axiom_node_t *foo_node = NULL;
+axiom_element_t *foo_ele = NULL;
+axiom_node_t *bar_node = NULL;
+axiom_element_t *bar_ele = NULL;
+
+foo_ele = axiom_element_create(env, NULL, "FOO", NULL, &amp;foo_node);
+bar_ele = axiom_element_create(env, NULL, "BAR", NULL. &amp;bar_node);
+axiom_node_add_child(foo_node, env, bar_node);
+
+</pre></div>
+ <p>Alternatively, we can pass the <code>foo_node</code> as the parent node at
+the time of creating the <code>bar_ele</code> as follows.</p>
+ <div class="source"><pre> bar_ele = axiom_element_create(env, foo_node, "BAR", NULL, &amp;bar_node);
+
+</pre></div>
+ <p>The following shows important methods available in
+<code>axiom_element</code> to be used to deal with namespaces.</p><p><b>Code Listing 5</b></p>
+ <div class="source"><pre>axiom_namespace_t *
+axiom_element_declare_namespace(axiom_element_t *om_ele,
+ const axutil_env_t *env,
+ axiom_node_t *om_node,
+ axiom_namespace_t *om_ns);
+
+axiom_namespace_t *
+axiom_element_find_namespace(axiom_element_t *om_ele,
+ const axutil_env_t *env,
+ axiom_node_t *om_node,
+ axis2_char_t *uri,
+ axis2_char_t *prefix);
+
+axiom_namespace_t *
+axiom_element_find_declared_namespace(axiom_element_t *om_element,
+ const axutil_env_t *env,
+ axis2_char_t *uri,
+ axis2_char_t *prefix);
+
+axis2_status_t
+axiom_element_set_namespace(axiom_element_t *om_element,
+ const axutil_env_t *env,
+ axiom_namespace_t *ns,
+ axiom_node_t *element_node);
+
+</pre></div>
+ <p>An <code>axiom_element</code> has a namespace list, the declared
+namespaces, and a pointer to its own namespace if one exists.</p><p>The <code>axiom_element_declare_namespace</code> function is straight
+forward. It adds a namespace to the declared namespace list. Note that a
+namespace that is already declared will not be declared again.</p><p><code>axiom_element_find_namespace</code> is a very handy method to locate
+a namespace in the AXIOM tree. It searches for a matching namespace in its
+own declared namespace list and jumps to the parent if it's not found. The
+search progresses up the tree until a matching namespace is found or the root
+has been reached.</p><p><code>axiom_element_find_declared_namespace</code> can be used to search
+for a namespace in the current element's declared namespace list.</p><p><code>axiom_element_set_namespace</code> sets <code>axiom_element</code>'s
+own namespace. Note that an element's own namespace should be declared in its
+own namespace declaration list or in one of its parent elements. This method
+first searches for a matching namespace using
+<code>axiom_element_find_namespace</code> and if a matching namespace is not
+found, a namespace is declared to this <code>axiom_element</code>'s namespace
+declarations list before setting the own namespace reference.</p><p>The following sample code segment shows how the namespaces are dealt with
+in AXIOM.</p><p><b>Code Listing 6</b></p>
+ <div class="source"><pre>axiom_namespace_t *ns1 = NULL;
+axiom_namespace_t *ns2 = NULL;
+axiom_namespace_t *ns3 = NULL;
+
+axiom_node_t *root_node = NULL;
+axiom_element_t *root_ele = NULL;
+
+axiom_node_t *ele1_node = NULL;
+axiom_element_t *ele1 = NULL;
+
+axiom_node_t *text_node = NULL;
+axiom_text_t *om_text = NULL;
+
+ns1 = axiom_namespace_create(env, "bar", "x");
+ns2 = axiom_namespace_create(env, "bar1", "y");
+
+root_ele = axiom_element_create(env, NULL , "root", ns1, &amp;root_node);
+ele1 = axiom_element_create(env, root_node, "foo", ns2, &amp;ele1_node);
+om_text = axiom_text_create(env, ele1_node, "blah", &amp;text_node);
+
+</pre></div>
+ <p></p><p>Serialization of the root element produces the following XML:</p>
+ <div class="source"><pre>&lt;x:root xmlns:x="bar"&gt;
+ &lt;y:foo xmlns:y="bar1"&gt;blah&lt;/y:foo&gt;
+&lt;/x:root&gt;
+
+</pre></div>
+ <p>If we want to produce</p>
+ <div class="source"><pre>&lt;x:foo xmlns:x="bar" xmlns:y="bar1"&gt;Test&lt;/x:foo&gt;
+
+</pre></div>
+ <p>we can use set_namespace and declare namespace functions as follows.</p>
+ <div class="source"><pre>axiom_node_t *foo_node = NULL;
+axiom_element_t *foo_ele = NULL;
+axiom_namespace_t *ns1 = NULL;
+axiom_namespace_t *ns2 = NULL;
+
+foo_ele = axiom_element_create(env, NULL,"foo" ,NULL, &amp;foo_node);
+
+ns1 = axiom_namespace_create(env, "bar", "x");
+ns2 = axiom_namespace_create(env, "bar1","y");
+
+axiom_element_set_namespace(foo_ele, env, ns1, foo_node);
+axiom_element_declare_namespace(foo_ele, env, ns2, foo_node);
+axiom_element_set_text(foo_ele, env, "Test", &amp;foo_node);
+</pre></div>
+ <p><a id="Traversing"></a></p></div><div class="subsection"><a name="Traversing"></a><h3>Traversing</h3><p>Traversing the AXIOM structure can be done by obtaining an iterator
+struct. You can either call the appropriate function on an AXIOM element or
+create the iterator manually. AXIOM/C offers three iterators to traverse the
+AXIOM structure. They are:</p><ul>
+ <li>axiom_children_iterator_t</li>
+ <li>axiom_child_element_iterator_t</li>
+ <li>axiom_children_qname_iterator_t</li>
+</ul><p>The iterator supports the 'AXIOM way' of accessing elements and is more
+convenient than a list for sequential access. The following code sample shows
+how the children can be accessed. The children can be of type
+<code>AXIOM_TEXT</code> or <code>AXIOM_ELEMENT</code>.</p><p><b>Code Listing 7</b></p>
+ <div class="source"><pre>axiom_children_iterator_t *children_iter = NULL;
+children_iter = axiom_element_get_children(om_ele, env, om_node);
+if(NULL != children_iter )
+{
+ while(axiom_children_iterator_has_next(children_iter, env))
+ {
+ axiom_node_t *node = NULL;
+ node = axiom_children_iterator_next(children_iter, env);
+ if(NULL != node)
+ {
+ if(axiom_node_get_node_type(node, env) == AXIOM_ELEMENT)
+ {
+ /* processing logic goes here */
+ }
+ }
+
+ }
+}
+
+</pre></div>
+ <p>Apart from this, every <code>axiom_node_t</code> struct has links to its
+siblings. If a thorough navigation is needed, the
+<code>axiom_node_get_next_sibling()</code> and
+<code>axiom_node_get_previous_sibling()</code> functions can be used. A
+restrictive set can be chosen by using
+<code>axiom_element_xxx_with_qname()</code> methods. The
+<code>axiom_element_get_first_child_with_qname()</code> method returns the
+first child that matches the given <code>axutil_qname_t</code> and
+<code>axiom_element_get_children_with_qname()</code> returns
+<code>axiom_children_qname_iterator_t</code> which can be used to traverse
+all the matching children. The advantage of these iterators is that they
+won't build the whole object structure at once; it builds only what is
+required.</p><table class="bodyTable"><tbody>
+ <tr class="a"><td><img src="images/OM005.gif" alt="" width="35" height="57"></img></td><td class="special-td">Internally, all iterator implementations stay
+ one step ahead of their apparent location to provide the correct
+ value for the <code>has_next()</code> function . This hidden
+ advancement can build elements that are not intended to be built at
+ all.</td><td></td></tr>
+ </tbody></table><p>
+
+</p><p></p><p><a id="Serialization"></a></p></div><div class="subsection"><a name="Serialization"></a><h3>Serialization</h3><p>AXIOM can be serialized using the <code>axiom_node_serialize</code>
+function. The serialization uses <code>axiom_xml_writer.h</code> and
+<code>axiom_output.h</code> APIs.</p><p>Here is an example that shows how to write the output to the console (we
+have serialized the SOAP envelope created in code listing 1).</p><p><b>Code Listing 8</b></p>
+ <div class="source"><pre>axiom_xml_writer_t *xml_writer = NULL;
+axiom_output_t *om_output = NULL;
+axis2_char_t *buffer = NULL;
+
+..............
+
+xml_writer = axiom_xml_writer_create(env, NULL, 0, 0);
+om_output = axiom_output_create(env, xml_writer);
+
+axiom_soap_envelope_serialize(envelope, env, om_output);
+buffer = (axis2_char_t*)axis2_xml_writer_get_xml(xml_writer, env);
+printf("%s ", buffer);
+
+</pre></div>
+ <p>An easy way to serialize is to use the <code>to_string</code> function in
+<code>om_element</code></p><p><b>Code Listing 9</b></p>
+ <div class="source"><pre>axis2_char_t *xml_output = NULL;
+axiom_node_t *foo_node = NULL;
+axiom_element_t *foo_ele = NULL;
+axiom_namespace_t* ns = NULL;
+
+ns = axiom_namespace_create(env, "bar", "x");
+
+foo_ele = axiom_element_create(env, NULL, "foo", ns, &amp;foo_node);
+
+axiom_element_set_text(foo_ele, env, "EASY SERAILIZATION", foo_node);
+
+xml_output = axiom_element_to_string(foo_ele, env, foo_node);
+
+printf("%s", xml_output);
+AXIS2_FREE(env-&gt;allocator, xml_output);
+
+</pre></div>
+ <p>Note that freeing the returned buffer is the user's responsibility.</p><p><a id="Reader_and_Writer"></a></p></div><div class="subsection"><a name="Using_axiom_xml_reader_and_axiom_xml_writer"></a><h3>Using axiom_xml_reader and axiom_xml_writer</h3><p><code>axiom_xml_reader</code> provides three create functions that can be
+used for different XML input sources.</p><ul>
+ <li><code>axiom_xml_reader_create_for_file</code> can be used to read from
+ a file</li>
+ <li><code>axiom_xml_reader_create_for_io</code> uses a user defined
+ callback function to pull XML</li>
+ <li><code>axiom_xml_reader_create_for_memory</code> can be used to read
+ from an XML string that is in a character buffer</li>
+</ul><p>
+
+
+ls of the latest version can be found on the Apache Axis2/C
+<ul>
+ <li><code>axiom_xml_writer_create_for_file</code> can be used to write to a
+ file</li>
+ <li><code>axiom_xml_writer_create_for_memory</code> can be used to write to
+ an internal memory buffer and obtain the XML string as a character
+ buffer</li>
+</ul></p><p></p><p>Please refer to <code>axiom_xml_reader.h</code> and
+<code>axiom_xml_writer.h</code> for more information.</p><p></p><p><a id="Mem_Leaks"></a></p></div><div class="subsection"><a name="How_to_Avoid_Memory_Leaks_and_Double_Frees_When_Using_AXIOM"></a><h3>How to Avoid Memory Leaks and Double Frees When Using AXIOM</h3><p>You have to be extremely careful when using AXIOM, in order to avoid
+memory leaks and double free errors. The following guidelines will be
+extremely useful:</p><p>1. The <code>axiom_element</code> struct keeps a list of attributes and a
+list of namespaces, when an <code>axiom_namespace</code> pointer or an
+<code>axiom_attribute</code> pointer is added to these lists, which will be
+freed when the <code>axiom_element</code> is freed. Therefore a pointer to a
+namespace or an attribute should not be freed, once it is used with an
+<code>axiom_element</code>.</p><p>To avoid any inconvenience, clone functions have been implemented for both
+the <code>axiom_namespace</code> and <code>axiom_attribute</code>
+structures.</p><p>2. AXIOM returns shallow references to its string values. Therefore, when
+you want deep copies of returned values, the <code>axutil_strdup()</code>
+function should be used to avoid double free errors.</p><p>Example</p><p><code>axiom_namespace_t *ns = NULL;</code></p><p><code>axis2_char_t *uri = NULL;</code></p><p><code>ns = axiom_namespace_create(env, "http://ws.apache.org",
+"AXIOM");</code></p><p><code>uri = axiom_namespace_get_uri(ns, env);</code></p><p><code>/* now uri points to the same place where namespace struct's uri <br></br>
+pointer is pointing. Therefore following will cause a double free
+*/</code></p><p><code>AXIS2_FREE(env-&gt;allocator, uri);</code></p><p><code>axiom_namespace_free(ns, env);</code></p><p>3. When creating AXIOM programatically, if you are declaring a namespace
+with an <code>axiom_element</code>, it is advisable to find whether the
+namespace is already available in the elements scope using the
+<code>axiom_element_find_namespace</code> function. If available, that
+pointer can be used instead of creating another namespace struct instance to
+minimize memory usage.</p><p></p><p><a id="Complete_Sample"></a></p></div><div class="subsection"><a name="Complete_Code_for_the_AXIOM_Based_Document_Building_and_Serialization"></a><h3>Complete Code for the AXIOM Based Document Building and Serialization</h3><p>The following code segment shows how to use AXIOM for building a document
+completely and then serializing it into text, pushing the output to the
+console.</p><p></p><p><b>Code Listing 10</b></p>
+ <div class="source"><pre>#include &lt;axiom.h&gt;
+#include &lt;axis2_util.h&gt;
+#include &lt;axutil_env.h&gt;
+#include &lt;axutil_log_default.h&gt;
+#include &lt;axutil_error_default.h&gt;
+#include &lt;stdio.h&gt;
+
+FILE *f = NULL;
+int read_input_callback(char *buffer, int size, void* ctx)
+{
+     fread(buffer, (char), size, f);
+}
+int close_input_callback(void *ctx)
+{
+     fclose(f);
+}
+axutil_env_t * create_environment()
+{
+    axutil_allocator_t *allocator = NULL;
+    axutil_env_t *env = NULL;
+    axutil_log_t *log = NULL;
+
+    axutil_error_t *error = NULL;
+    allocator = axutil_allocator_init(NULL);
+    log = axutil_log_create(allocator, NULL, NULL);
+
+    error = axutil_error_create(allocator);
+    env = axutil_env_create_with_error_log(allocator, error, log);
+     env;
+}
+
+build_and_serialize_om(axutil_env_t *env)
+{
+    axiom_node_t *root_node = NULL;
+
+    axiom_element_t *root_ele = NULL;
+    axiom_document_t *document = NULL;
+    axiom_stax_builder_t *om_builder = NULL;
+
+    axiom_xml_reader_t *xml_reader = NULL;
+    axiom_xml_writer_t *xml_writer = NULL;
+    axiom_output_t *om_output = NULL;
+
+    axis2_char_t *buffer = NULL;
+    
+    f = fopen("test.xml","r");
+    xml_reader = axiom_xml_reader_create_for_io(env, read_input_callback,
+                                                    close_input_callback, NULL, NULL);
+    (!xml_reader)
+         -1;
+
+    om_builder = axiom_stax_builder_create(env, xml_reader);
+    (!om_builder)
+    {
+        axiom_xml_reader_free(xml_reader, env);
+         AXIS2_FAILURE;
+    }
+    document = axiom_stax_builder_get_document(om_builder, env);
+    (!document)
+    {
+         axiom_stax_builder_free(om_builder, env);
+         AXIS2_FAILURE;
+    }
+    
+    root_node = axiom_document_get_root_element(document, env);
+    (!root_node)
+    {
+        axiom_stax_builder_free(om_builder, env);
+         AXIS2_FAILURE;
+    }        
+    (root_node)
+    {
+        (axiom_node_get_node_type(root_node, env) == AXIOM_ELEMENT)
+        {
+            root_ele = (axiom_element_t*)axiom_node_get_data_element(root_node, env);
+            (root_ele)
+            {
+ printf(" %s" ,axiom_element_get_localname(root_ele, env));
+ }
+ }
+ }
+
+ axiom_document_build_all(document, env);
+ axiom_document_build_all(document, env);
+
+ xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, AXIS2_XML_PARSER_TYPE_BUFFER);
+
+ om_output = axiom_output_create(env, xml_writer);
+
+ axiom_node_serialize(root_node, env, om_output);
+
+ buffer = (axis2_char_t*)axiom_xml_writer_get_xml(xml_writer, env);
+
+ printf("The output XML is -&gt;&gt;&gt;&gt;\n %s ", buffer);
+  
+    
+    
+    axiom_output_free(om_output, env);
+    
+    
+    axiom_stax_builder_free(om_builder, env);
+    
+     AXIS2_SUCCESS;
+    
+}
+int main()
+{
+    int status = AXIS2_SUCCESS;
+    
+    axutil_env_t *env = NULL;
+    axutil_allocator_t *allocator = NULL;
+    env = create_environment();
+
+    status = build_and_serialize_om(env);
+
+    (status == AXIS2_FAILURE)
+    {
+        printf(" build AXIOM failed");
+    }
+    
+    axutil_env_free(env);
+    
+     0;
+}
+
+
+</pre></div>
+ </div></div></div></div><div class="clear"><hr></hr></div></body></html>