diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | misc/Makefile | 9 | ||||
| -rw-r--r-- | misc/pres_xml-fasttrack_en.tex | 426 | ||||
| -rw-r--r-- | misc/samples/.gitignore | 2 | ||||
| -rw-r--r-- | misc/samples/Makefile | 10 | ||||
| -rw-r--r-- | misc/samples/xml_dom.c | 55 | ||||
| -rw-r--r-- | misc/samples/xml_full.xml | 24 | ||||
| -rw-r--r-- | misc/samples/xml_sax.c | 109 | ||||
| -rw-r--r-- | misc/samples/xml_small.xml | 14 | ||||
| -rw-r--r-- | misc/section.tex | 3 |
10 files changed, 653 insertions, 1 deletions
@@ -1,4 +1,4 @@ -SUBDIRS = application-devel flash-memory frameworks kernel-devel linux-basics protocols realtime security +SUBDIRS = application-devel flash-memory frameworks kernel-devel linux-basics protocols realtime security misc default: make all diff --git a/misc/Makefile b/misc/Makefile new file mode 100644 index 0000000..7d530a5 --- /dev/null +++ b/misc/Makefile @@ -0,0 +1,9 @@ +all: + for pdf in `ls -1 handout_*.tex pres_*.tex` ; do \ + TEXINPUTS=`pwd`/../..:.:..:$(TEXINPUTS) pdflatex $$pdf; \ + TEXINPUTS=`pwd`/../..:.:..:$(TEXINPUTS) pdflatex $$pdf; \ + done + +clean: + rm -f *.aux *.log *.pdf *.log *.snm *.toc *.vrb *.nav *.out + diff --git a/misc/pres_xml-fasttrack_en.tex b/misc/pres_xml-fasttrack_en.tex new file mode 100644 index 0000000..35027ee --- /dev/null +++ b/misc/pres_xml-fasttrack_en.tex @@ -0,0 +1,426 @@ +\def\lximg{/usr/share/lx/icons/fueller.png} + +\input{configpres} + +% ------------------------ +\section{Programming in C/C++} + +% ------------------------ +\subsection{XML Processing} + +\title{XML Processing in C/C++} +\maketitle + +\def\lximg{none} + +\begin{frame} +\frametitle{Contents} +\tableofcontents +\end{frame} + +% ------------------------ +\subsubsection{Basics} + +\begin{frame}[fragile] +\frametitle{What is XML?} +XML is +\begin{itemize} +\item a Markup Language to describe structured data +\item extensible by defining new data type definitions +\item human readable as well as machine readable +\end{itemize} + +{ \tiny +\begin{verbatim} +<?xml version="1.0"?> +<store> +<!-- Sample Bookstore --> + <book isbn="10000001"> + <title>The Lord Of The Rings</title> + <author>J.R.R. Tolkien</author> + </book> + <cd> + <title>The Wall</title> + <artist>Pink Floyd</artist> + <track length="3:40">Another Brick in the Wall</track> + <track length="5:33">Mother</track> + </cd> +</store> +\end{verbatim} +} +\end{frame} + +% ------------------------ +\subsubsection{Processing} + +\begin{frame}[fragile] +\frametitle{Own parser vs. using a common library} +Using a common library is the preferred solution +\begin{itemize} +\item XML can get very complex +\item own parsers might struggle with some exotic but allowed constructs +\item common libraries are (mostly) well tested +\item rapid prototyping with common libraries +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{GNOME XML library} +\begin{itemize} +\item libxml2 is the most common XML library for Linux and C/C++ +\item provides a large toolset for nearly all XML problems +\item can be used for small XML junks as well as for huge XML files or streams +\item support Document Object Model (DOM) as well as Simple API for XML (SAX) +\item support parse, generate and validate +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Document Object Model (DOM)} +\begin{itemize} +\item DOM Parser creates a tree representation of the XML junk in main memory +\item Pros: + \begin{itemize} + \item navigation support + \item model can be modified + \item easy export of an existing model + \end{itemize} +\item Cons: + \begin{itemize} + \item large XML junks need lot of main memory + \item no stream handling support + \item slow for large XML files + \end{itemize} +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Simple API for XML (SAX)} +\begin{itemize} +\item DOM tree parser uses SAX2 internally! +\item SAX uses callbacks for parsing events (start element, end element etc.) +\item Pros: + \begin{itemize} + \item lean and fast + \item large-file and stream handling support + \item memory footprint depends on callback implementation + \end{itemize} +\item Cons: + \begin{itemize} + \item no navigation support + \item no XML generation support + \end{itemize} +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Recommendation} +\begin{itemize} +\item choose the right parser for the right use case +\item DOM: + \begin{itemize} + \item small files + \item navigate/modify/generate + \item data model validation (DTD) + \end{itemize} +\item SAX2: + \begin{itemize} + \item streams or large files + \item preselect XML junks + \end{itemize} +\item combine SAX2 and DOM if necessary +\end{itemize} +\end{frame} + +% ------------------------ +\subsubsection{Examples} + +\begin{frame}[fragile] +\frametitle{DOM main()} +{ \tiny +\begin{verbatim} +#include <stdio.h> +#include <libxml/parser.h> +#include <libxml/tree.h> + +static void print_element_names(xmlNode *); + +int main(int argc, char **argv) { + xmlDocPtr my_doc = NULL; + xmlNode *root_element = NULL; + + my_doc = xmlReadFile(argv[1], NULL, 0); // parse XML file + + root_element = xmlDocGetRootElement(my_doc); + + print_element_names(root_element); // output + + xmlFreeDoc(my_doc); + xmlCleanupParser(); + return 0; +} +\end{verbatim} +} +\end{frame} + +\begin{frame}[fragile] +\frametitle{DOM tree navigation and output} +{ \tiny +\begin{verbatim} +static void print_element_names(xmlNode * a_node) +{ + xmlNode *cur_node = NULL; + + for (cur_node = a_node; cur_node; cur_node = cur_node->next) { + if (cur_node->type == XML_ELEMENT_NODE) { + printf("node type: Element, name: %s\n", cur_node->name); + } + + print_element_names(cur_node->children); + } +} +\end{verbatim} +} +\end{frame} + +\begin{frame}[fragile] +\frametitle{DOM: Input / Output} +\begin{columns} +\begin{column}{5cm} +{ \tiny +\begin{verbatim} +<?xml version="1.0"?> +<store> +<!-- Sample Bookstore --> +<book isbn="10000001"> +<title>The Lord Of The Rings</title> +<author>J.R.R. Tolkien</author> +</book> +<cd> +<title>The Wall</title> +<artist>Pink Floyd</artist> +<track length="3:40"> + Another Brick in the Wall</track> +<track length="5:33">Mother</track> +</cd> +</store> +\end{verbatim} +} +\end{column} +\begin{column}{5cm} +{ \tiny +\begin{verbatim} + + +node type: Element, name: store + +node type: Element, name: book +node type: Element, name: title +node type: Element, name: author + +node type: Element, name: cd +node type: Element, name: title +node type: Element, name: artist +node type: Element, name: track + +node type: Element, name: track + + +\end{verbatim} +} +\end{column} +\end{columns} +\end{frame} + +\begin{frame}[fragile] +\frametitle{SAX2 main()} +{ \tiny +\begin{verbatim} +/* + * Simple SAX example + */ + +#include <string.h> +#include <libxml/parser.h> +#include <libxml/tree.h> + +static int cb_total = 0; + +int main(int argc, char **argv) { + cb_total = 0; + + xmlSAXUserParseFile(debugSAXHandler, NULL, argv[1]); + + fprintf(stdout, "\ncallback calls: %d\n", cb_total); + + xmlCleanupParser(); + xmlMemoryDump(); + + return 0; +} +\end{verbatim} +} +\end{frame} + +\begin{frame}[fragile] +\frametitle{SAX2 callback implementations} +{ \tiny +\begin{verbatim} +static void cb_start_document(void *ctx ATTRIBUTE_UNUSED) +{ + cb_total++; + fprintf(stdout, "SAX.startDocument()\n"); +} + +static void cb_end_document(void *ctx ATTRIBUTE_UNUSED) +{ + cb_total++; + fprintf(stdout, "SAX.endDocument()\n"); +} + +static void cb_characters(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len) +{ + char output[40]; + int i; + + cb_total++; + for (i = 0;(i<len) && (i < 30);i++) + output[i] = ch[i]; + output[i] = 0; + + fprintf(stdout, "SAX.characters(%s, %d)\n", output, len); +} +\end{verbatim} +} +\end{frame} + +\begin{frame}[fragile] +\frametitle{SAX2 callback structure} +{ \tiny +\begin{verbatim} +xmlSAXHandler debugSAXHandlerStruct = { + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + cb_start_document, + cb_end_document, + cb_start_element, + cb_end_element, + NULL, + cb_characters, + NULL, NULL, + cb_comment, + NULL, NULL, NULL, NULL, NULL, NULL, + 1 +}; +xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct; +\end{verbatim} +} +\end{frame} + +\begin{frame}[fragile] +\frametitle{SAX: Input / Output - Outline} +\begin{columns} +\begin{column}{5cm} +{ \tiny +\begin{verbatim} +<?xml version="1.0"?> +<store> + + +<!-- Sample Bookstore --> + + +[...] +</store> + +\end{verbatim} +} +\end{column} +\begin{column}{5cm} +{ \tiny +\begin{verbatim} +SAX.startDocument() +SAX.startElement(store) +SAX.characters( +, 1) +SAX.comment( Sample Bookstore ) +SAX.characters( +, 1) +[...] +SAX.endElement(store) +SAX.endDocument() +\end{verbatim} +} +\end{column} +\end{columns} +\end{frame} + +\begin{frame}[fragile] +\frametitle{SAX: Input / Output - Element} +\begin{columns} +\begin{column}{5cm} +{ \tiny +\begin{verbatim} +<book isbn="10000001"> + + +<title>The Lord Of The Rings</title> + + + + +<author>J.R.R. Tolkien</author> + + + + +</book> +\end{verbatim} +} +\end{column} +\begin{column}{5cm} +{ \tiny +\begin{verbatim} +SAX.startElement(book, isbn='10000001') +SAX.characters( +, 1) +SAX.startElement(title) +SAX.characters(The Lord Of The Rings, 21) +SAX.endElement(title) +SAX.characters( +, 1) +SAX.startElement(author) +SAX.characters(J.R.R. Tolkien, 13) +SAX.endElement(author) +SAX.characters( +, 1) +SAX.endElement(book) +\end{verbatim} +} +\end{column} +\end{columns} +\end{frame} + +% ------------------------ +\subsection{} +\begin{frame} +\frametitle{References} + +XML on W3C: +\begin{itemize} +\item \url{http://www.w3.org/XML/} +\item \url{http://www.w3.org/TR/REC-xml/} +\end{itemize} + +GNOME XML Library: +\begin{itemize} +\item \url{http://www.xmlsoft.org/} +\end{itemize} + +Wikipedia: +\begin{itemize} +\item \url{http://en.wikipedia.org/wiki/XML} +\end{itemize} +\end{frame} + +\input{tailpres} diff --git a/misc/samples/.gitignore b/misc/samples/.gitignore new file mode 100644 index 0000000..805c89c --- /dev/null +++ b/misc/samples/.gitignore @@ -0,0 +1,2 @@ +xml_dom +xml_sax diff --git a/misc/samples/Makefile b/misc/samples/Makefile new file mode 100644 index 0000000..cd411f2 --- /dev/null +++ b/misc/samples/Makefile @@ -0,0 +1,10 @@ +XML_TARGETS=xml_dom xml_sax +XML_CFLAGS=$(shell xml2-config --cflags) + +all: $(XML_TARGETS) + +%: %.c + $(CC) $(XML_CFLAGS) -g -O0 -l xml2 -o $@ $^ + +clean: + rm -r $(XML_TARGETS) diff --git a/misc/samples/xml_dom.c b/misc/samples/xml_dom.c new file mode 100644 index 0000000..66166dd --- /dev/null +++ b/misc/samples/xml_dom.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <libxml/parser.h> +#include <libxml/tree.h> + +static void print_element_names(xmlNode *); + +int main(int argc, char **argv) { + xmlDocPtr my_doc = NULL; + xmlNode *root_element = NULL; + char *filename; + int rc = 1; + + if (argc != 2) { + rc = 1; + goto out; + } + filename = argv[1]; + + /* ABI checking (opt.) */ + LIBXML_TEST_VERSION + + my_doc = xmlReadFile(filename, NULL, 0); + if (!my_doc) { + rc = 1; + goto out_cleanup; + } + + /*Get the root element node */ + root_element = xmlDocGetRootElement(my_doc); + + print_element_names(root_element); + + rc = 0; +out_freedoc: + /* Free parsed DOM tree */ + xmlFreeDoc(my_doc); +out_cleanup: + /* Cleanup function for the XML library */ + xmlCleanupParser(); +out: + return(rc); +} + +static void print_element_names(xmlNode * a_node) +{ + xmlNode *cur_node = NULL; + + for (cur_node = a_node; cur_node; cur_node = cur_node->next) { + if (cur_node->type == XML_ELEMENT_NODE) { + printf("node type: Element, name: %s\n", cur_node->name); + } + + print_element_names(cur_node->children); + } +} diff --git a/misc/samples/xml_full.xml b/misc/samples/xml_full.xml new file mode 100644 index 0000000..c8b0ecd --- /dev/null +++ b/misc/samples/xml_full.xml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<store> +<!-- Sample Bookstore --> +<book isbn="10000001"> +<title>The Lord Of The Rings</title> +<author>J.R.R. Tolkien</author> +</book> +<book isbn="10000002"> +<title>Maitreyi</title> +<author>Mircea Eliade</author> +</book> +<cd> +<title>The Wall</title> +<artist>Pink Floyd</artist> +<track length="3:40">Another Brick in the Wall</track> +<track length="5:33">Mother</track> +</cd> +<cd> +<title>Come on Over</title> +<artist>Shania Twain</artist> +<track length="4:40">From This Moment On</track> +<track length="3:33">You're Still The One</track> +</cd> +</store> diff --git a/misc/samples/xml_sax.c b/misc/samples/xml_sax.c new file mode 100644 index 0000000..b586a21 --- /dev/null +++ b/misc/samples/xml_sax.c @@ -0,0 +1,109 @@ +/* + * Simple SAX example + */ + +#include <string.h> +#include <libxml/parser.h> +#include <libxml/tree.h> + +static int cb_total = 0; + +/* + * Callback implementations + */ +static void +cb_start_document(void *ctx ATTRIBUTE_UNUSED) +{ + cb_total++; + fprintf(stdout, "SAX.startDocument()\n"); +} + +static void +cb_end_document(void *ctx ATTRIBUTE_UNUSED) +{ + cb_total++; + fprintf(stdout, "SAX.endDocument()\n"); +} + +static void +cb_start_element(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts) +{ + int i; + + cb_total++; + fprintf(stdout, "SAX.startElement(%s", (char *) name); + if (atts != NULL) { + for (i = 0;(atts[i] != NULL);i++) { + fprintf(stdout, ", %s='", atts[i++]); + if (atts[i] != NULL) + fprintf(stdout, "%s'", atts[i]); + } + } + fprintf(stdout, ")\n"); +} + +static void +cb_end_element(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name) +{ + cb_total++; + fprintf(stdout, "SAX.endElement(%s)\n", (char *) name); +} + +static void +cb_characters(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len) +{ + char output[40]; + int i; + + cb_total++; + for (i = 0;(i<len) && (i < 30);i++) + output[i] = ch[i]; + output[i] = 0; + + fprintf(stdout, "SAX.characters(%s, %d)\n", output, len); +} + +static void +cb_comment(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value) +{ + cb_total++; + fprintf(stdout, "SAX.comment(%s)\n", value); +} + +/* + * Define callback struct + */ +xmlSAXHandler debugSAXHandlerStruct = { + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + cb_start_document, + cb_end_document, + cb_start_element, + cb_end_element, + NULL, + cb_characters, + NULL, NULL, + cb_comment, + NULL, NULL, NULL, NULL, NULL, NULL, + 1 +}; +xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct; + +int main(int argc, char **argv) { + int rc; + + if (argc != 2) + return 1; + + cb_total = 0; + rc = xmlSAXUserParseFile(debugSAXHandler, NULL, argv[1]); + if (rc) + fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", rc); + + fprintf(stdout, "\ncallback calls: %d\n", cb_total); + + xmlCleanupParser(); + xmlMemoryDump(); + + return(0); +} diff --git a/misc/samples/xml_small.xml b/misc/samples/xml_small.xml new file mode 100644 index 0000000..6b38af4 --- /dev/null +++ b/misc/samples/xml_small.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<store> +<!-- Sample Bookstore --> +<book isbn="10000001"> +<title>The Lord Of The Rings</title> +<author>J.R.R. Tolkien</author> +</book> +<cd> +<title>The Wall</title> +<artist>Pink Floyd</artist> +<track length="3:40">Another Brick in the Wall</track> +<track length="5:33">Mother</track> +</cd> +</store> diff --git a/misc/section.tex b/misc/section.tex new file mode 100644 index 0000000..d12f8a2 --- /dev/null +++ b/misc/section.tex @@ -0,0 +1,3 @@ +% Dummy section file for misc topics. +% Please specify the related section directly in the presentation. +% \section{} |
