\chapter{Retrieving Data From An \ltext{XML} Datasource}

This chapter shows how to retrieve \ltext{XML} data from a standard data source.
Such source can be a file, an \ltext{HTTP} object or a text string.

\section{A Very Simple Example}

This section describes a very simple \ltext{XML} application.
It parses \ltext{XML} data from a stream and dumps it to the standard output.
While its use is very limited, it shows how to set up a parser and parse an
\ltext{XML} document.

\begin{example}
\xkeyword{import} nanoxml.*;\xcallout{1}
\xkeyword{import} java.io.*;

\xkeyword{public class} DumpXML
\{
~~\xkeyword{public static void} main(String[] args)
~~~~\xkeyword{throws} Exception
~~\{
~~~~XMLElement xml = new XMLElement();\xcallout{2}
~~~~FileReader reader = new FileReader("test.xml");
~~~~xml.parseFromReader(reader);\xcallout{3}
~~~~System.out.println(xml);\xcallout{4}
~~\}
\}
\end{example}

\begin{callout}
  \coitem
    The \ltext{NanoXML} classes are located in the package \packagename{nanoxml}.
  \coitem
    This command creates an empty \ltext{XML} element.
  \coitem
    The method \methodname{parseFromReader} parses the data in the file
    \filename{test.xml} and fills the empty element.
  \coitem
    The \ltext{XML} element is dumped to the standard output.
\end{callout}

\section{Analyzing The Data}

You can easily traverse the logical tree generated by the parser.
By calling one of the \methodname{parse*} methods, you fill an empty
\ltext{XML} element with the parsed contents.
Every such object can have a name, attributes, \ltext{\#PCDATA} content and child
objects.

The following XML data:

\begin{example}
$<$FOO attr1="fred" attr2="barney"$>$
~~$<$BAR a1="flintstone" a2="rubble"$>$
~~~~Some data.
~~$<$/BAR$>$
~~$<$QUUX/$>$
$<$/FOO$>$
\end{example}

is parsed to the following objects:

\begin{itemize}
  \item[] Element FOO:
    \begin{itemize}
      \item[] Attributes = \{ "attr1"="fred", "attr2"="barney" \}
      \item[] Children = \{ BAR, QUUX \}
      \item[] PCData = null
    \end{itemize}
  \item[] Element BAR:
    \begin{itemize}
      \item[] Attributes = \{ "a1"="flintstone", "a2"="rubble" \}
      \item[] Children = \{\}
      \item[] PCData = "Some data."
    \end{itemize}
  \item[] Element QUUX:
    \begin{itemize}
      \item[] Attributes = \{\}
      \item[] Children = \{\}
      \item[] PCData = null
    \end{itemize}
\end{itemize}

You can retrieve the name of an element using the method \methodname{getName},
thus:

\begin{example}
FOO.getName() $\to$ "FOO"
\end{example}

You can enumerate the attribute names using the method
\methodname{enumerateAttributeNames}:

\begin{example}
Enumeration enum = FOO.enumerateAttributeNames();
\xkeyword{while} (enum.hasMoreElements()) \{
~~System.out.print(enum.nextElement());
~~System.out.print(' ');
\}
$\to$ attr1 attr2
\end{example}

You can retrieve the value of an attribute using \methodname{getAttribute}:

\begin{example}
FOO.getAttribute("attr1") $\to$ "fred"
\end{example}

The child elements can be enumerated using the method
\methodname{enumerateChildren}:

\begin{example}
Enumeration enum = FOO.enumerateChildren();
\xkeyword{while} (enum.hasMoreElements()) \{
~~XMLElement child = (XMLElement) enum.nextElement();
~~System.out.print(child.getName() + ' ');
\}
$\to$ BAR QUUX
\end{example}

If the element contains parsed character data (\ltext{\#PCDATA}) as its only
child.
You can retrieve that data using \methodname{getContent}:

\begin{example}
BAR.getContent() $\to$ "Some data."
\end{example}

Note that in \ltext{NanoXML/Lite}, a child cannot have children and
\ltext{\#PCDATA} content at the same time.

\section{Generating \ltext{XML}}

You can very easily create a tree of \ltext{XML} elements or modify an existing
one.
To create a new tree, just create an \classname{XMLElement} object:

\begin{example}
XMLElement elt = new XMLElement("ElementName");
\end{example}

You can add an attribute to the element by calling \methodname{setAttribute}:

\begin{example}
elt.setAttribute("key", "value");
\end{example}

You can add a child element to an element by calling \methodname{addChild}:

\begin{example}
XMLElement child = new XMLElement("Child");
elt.addChild(child);
\end{example}

If an element has no children, you can add \ltext{\#PCDATA} content to it using
\methodname{setContent}:

\begin{example}
child.setContent("Some content");
\end{example}

Note that in \ltext{NanoXML/Lite}, a child cannot have children and
\ltext{\#PCDATA} content at the same time.

When you have created or edited the \ltext{XML} element tree, you can write it
out to an output stream or writer using the method \methodname{toString}:

\begin{example}
java.io.PrintWriter output = ...;
XMLElement xmltree = ...;
output.println(xmltree);
\end{example}
