source: sources/src/dataFormatXmlProcessor.cc @ 1464:3f6711617be1

Revision 1464:3f6711617be1, 23.1 KB checked in by niam, 22 months ago (diff)

{issue #58[resolved]} support for non-c++ exceptions

Line 
1/***************************************************************************
2 *            dataFormatXmlProcessor.cc
3 *
4 *  Wed Nov 30 2005
5 *  Copyright  2005  Dmytro Milinevskyy
6 *  milinevskyy@gmail.com
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License version 2.1 as published by
12 *  the Free Software Foundation;
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Lesser General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24/**
25 * vim indentation settings
26 * set tabstop=4
27 * set shiftwidth=4
28 */
29
30#include <libdodo/directives.h>
31
32#ifdef LIBXML2_EXT
33#include <libxml/parser.h>
34#include <libxml/xmlmemory.h>
35#endif
36
37#include <libdodo/dataFormatXmlProcessor.h>
38#include <libdodo/dataFormatXmlNode.h>
39#include <libdodo/dataFormatXmlProcessorEx.h>
40#include <libdodo/ioChannel.h>
41
42namespace dodo {
43    namespace data {
44        namespace format {
45            namespace xml {
46                /**
47                 * @struct __node__
48                 * @brief defines XML node properties
49                 */
50                struct __node__ {
51                    /**
52                     * constructor
53                     */
54                    __node__()
55#ifdef LIBXML2_EXT
56                        : node(NULL)
57#endif
58                    {
59                    }
60
61#ifdef LIBXML2_EXT
62                    /**
63                     * constructor
64                     * @param node defines node handle to assign
65                     */
66                    __node__(xmlNodePtr node) : node(node)
67                    {
68                    }
69#endif
70
71#ifdef LIBXML2_EXT
72                    xmlNodePtr node;    ///< represents internal libxml2 node data
73#endif
74                };
75
76                /**
77                 * @struct __doc__
78                 * @brief defines XML document properties
79                 */
80                struct __doc__ {
81                    /**
82                     * constructor
83                     */
84                    __doc__()
85#ifdef LIBXML2_EXT
86                        : doc(NULL)
87#endif
88                    {
89                    }
90
91#ifdef LIBXML2_EXT
92                    xmlDocPtr doc;      ///< represents internal libxml2 document data
93#endif
94                };
95            };
96        };
97    };
98};
99
100using namespace dodo::data::format::xml;
101
102__info__::__info__(const dodo::string &version,
103                   const dodo::string &encoding,
104                   const dodo::string &root,
105                   int              compression) : version(version),
106                                                   encoding(encoding),
107                                                   root(root),
108                                                   compression(compression)
109{
110}
111
112//-------------------------------------------------------------------
113
114__info__::__info__()
115{
116}
117
118//-------------------------------------------------------------------
119
120__definition__::__definition__() : allChildren(true),
121                                   allAttributes(true)
122{
123}
124
125//-------------------------------------------------------------------
126
127__definition__::__definition__(const dodo::string &name,
128                               const dodo::string &ns) : name(name),
129                                                       allChildren(true),
130                                                       allAttributes(true),
131                                                       ns(ns)
132{
133}
134
135//-------------------------------------------------------------------
136
137const dodo::string processor::statements[] = {
138    "<",
139    ":",
140    " ",
141    "xmlns:",
142    "=\"",
143    "\"",
144    "/>\r\n",
145    ">",
146    "<![CDATA[",
147    "]]>",
148    "</",
149};
150
151//-------------------------------------------------------------------
152
153#ifdef LIBXML2_EXT
154void
155errHandler(void *,
156           xmlErrorPtr)
157{
158}
159#endif
160
161//-------------------------------------------------------------------
162
163processor::processor(processor &)
164{
165}
166
167//-------------------------------------------------------------------
168
169processor::processor() : icaseNames(false),
170                         document(new __doc__)
171{
172#ifdef LIBXML2_EXT
173    xmlPedanticParserDefault(0);
174    xmlInitParser();
175    xmlSetStructuredErrorFunc(NULL, errHandler);
176#endif
177}
178
179//-------------------------------------------------------------------
180
181processor::~processor()
182{
183#ifdef LIBXML2_EXT
184    xmlFreeDoc(document->doc);
185    xmlCleanupParser();
186#endif
187
188    delete document;
189}
190
191//-------------------------------------------------------------------
192
193bool
194#if defined(LIBXML2_EXT)
195processor::isCDATA(const __node__ &node)
196#else
197processor::isCDATA(const __node__ &node UNUSED)
198#endif
199{
200#ifdef LIBXML2_EXT
201    xmlNodePtr xnode = node.node->children;
202    while (xnode != NULL) {
203        if (xnode->type == XML_CDATA_SECTION_NODE)
204            return true;
205
206        xnode = xnode->next;
207    }
208#endif
209
210    return false;
211}
212
213//-------------------------------------------------------------------
214
215node
216processor::process(const __definition__ &definition,
217                   const io::channel    &io)
218{
219#ifdef LIBXML2_EXT
220    xmlFreeDoc(document->doc);
221#endif
222
223    dodo::string buffer, bufferPart;
224    while (true) {
225        bufferPart = io.readString();
226        if (bufferPart.size() == 0)
227            break;
228
229        buffer += bufferPart;
230    }
231    bufferPart.clear();
232
233#ifdef LIBXML2_EXT
234    document->doc = xmlParseMemory(buffer.data(), buffer.size());
235    if (document->doc == NULL) {
236        xmlErrorPtr error = xmlGetLastError();
237
238        if (error == NULL)
239            dodo_throw exception::basic(exception::MODULE_DATAFORMATXMLPROCESSOR, PROCESSOREX_PARSEBUFFER, exception::ERRNO_LIBDODO, PROCESSOREX_EMPTYDOCUMENT, DATAFORMATXMLPROCESSOREX_EMPTYDOCUMENT_STR, __LINE__, __FILE__);
240        else
241            dodo_throw exception::basic(exception::MODULE_DATAFORMATXMLPROCESSOR, PROCESSOREX_PARSEBUFFER, exception::ERRNO_LIBXML2, error->code, error->message, __LINE__, __FILE__);
242    }
243#endif
244
245    return parse(definition);
246}
247
248//-------------------------------------------------------------------
249
250node
251#if defined(LIBXML2_EXT)
252processor::parse(const __definition__ &definition)
253#else
254processor::parse(const __definition__ &definition UNUSED)
255#endif
256{
257    node n;
258
259#ifdef LIBXML2_EXT
260    __node__ xnode = xmlDocGetRootElement(document->doc);
261    if (xnode.node == NULL) {
262        xmlErrorPtr error = xmlGetLastError();
263
264        if (error == NULL)
265            dodo_throw exception::basic(exception::MODULE_DATAFORMATXMLPROCESSOR, PROCESSOREX_PARSE, exception::ERRNO_LIBDODO, PROCESSOREX_NOROOTNODE, DATAFORMATXMLPROCESSOREX_NOROOTNODE_STR, __LINE__, __FILE__);
266        else
267            dodo_throw exception::basic(exception::MODULE_DATAFORMATXMLPROCESSOR, PROCESSOREX_PARSE, exception::ERRNO_LIBXML2, error->code, error->message, __LINE__, __FILE__);
268    }
269
270    xnode = findNode(definition, xnode);
271
272    if (xnode.node == NULL)
273        return n;
274
275    getNode(xnode, n);
276
277    getAttributes(definition, xnode, n.attributes);
278
279    n.CDATA = isCDATA(xnode);
280
281    if (xnode.node->children == NULL)
282        return n;
283
284    if (definition.allChildren) {
285        xnode.node = xnode.node->children;
286
287        node _n;
288
289        dodoArray<node> children;
290        dodoArray<node>::iterator i, j;
291
292        while (xnode.node != NULL) {
293            if (xnode.node->type != XML_ELEMENT_NODE) {
294                xnode.node = xnode.node->next;
295
296                continue;
297            }
298
299            getNode(xnode, _n);
300
301            getAttributes(xnode, _n.attributes);
302
303            _n.CDATA = isCDATA(xnode);
304
305            if (xnode.node->children != NULL) {
306                children = parse(__node__(xnode.node->children));
307                i = children.begin();
308                j = children.end();
309                for (; i != j; ++i)
310                    _n.nodeChildren[i->name].push_back(*i);
311            }
312
313            n.nodeChildren[(char *)xnode.node->name].push_back(_n);
314
315            initNode(_n);
316
317            xnode.node = xnode.node->next;
318        }
319    } else {
320        if (definition.children.size() > 0) {
321            dodoMap<dodo::string, __definition__>::const_iterator i(definition.children.begin()), j(definition.children.end());
322            for (; i != j; ++i)
323                n.nodeChildren.insert(std::make_pair(i->first, parse(i->second, xnode.node->children)));
324        }
325    }
326#endif
327
328    return n;
329}
330
331//-------------------------------------------------------------------
332
333dodoArray<node>
334#if defined(LIBXML2_EXT)
335processor::parse(const __definition__ &definition,
336                 const __node__       &node)
337#else
338processor::parse(const __definition__ &definition UNUSED,
339                 const __node__       &node UNUSED)
340#endif
341{
342    dodoArray<format::xml::node> nArr;
343
344#ifdef LIBXML2_EXT
345    xmlNodePtr xnode = node.node, subNode;
346
347    format::xml::node n;
348
349    strCmp cmpFunc = icaseNames ? xmlStrcasecmp : xmlStrcmp;
350
351    while (xnode) {
352        if (xnode->type != XML_ELEMENT_NODE) {
353            xnode = xnode->next;
354
355            continue;
356        }
357
358        if (definition.ns.size() > 0) {
359            if (xnode->ns == NULL) {
360                xnode = xnode->next;
361
362                continue;
363            }
364
365            if (cmpFunc(xnode->ns->prefix, (unsigned char *)definition.ns.data()) != 0) {
366                xnode = xnode->next;
367
368                continue;
369            }
370        }
371
372        if (cmpFunc(xnode->name, (unsigned char *)definition.name.data()) != 0) {
373            xnode = xnode->next;
374
375            continue;
376        }
377
378        initNode(n);
379
380        getNode(xnode, n);
381
382        getAttributes(definition, xnode, n.attributes);
383
384        n.CDATA = isCDATA(xnode);
385
386        if (definition.allChildren) {
387            subNode = xnode->children;
388
389            format::xml::node _n;
390
391            dodoArray<format::xml::node> chldrn;
392            dodoArray<format::xml::node>::iterator i, j;
393
394            while (subNode != NULL) {
395                if (subNode->type != XML_ELEMENT_NODE) {
396                    subNode = subNode->next;
397
398                    continue;
399                }
400
401                getNode(subNode, _n);
402
403                getAttributes(subNode, _n.attributes);
404
405                _n.CDATA = isCDATA(subNode);
406
407                if (subNode->children != NULL) {
408                    chldrn = parse(subNode->children);
409                    i = chldrn.begin();
410                    j = chldrn.end();
411                    for (; i != j; ++i)
412                        _n.nodeChildren[i->name].push_back(*i);
413                }
414
415                n.nodeChildren[(char *)subNode->name].push_back(_n);
416
417                initNode(_n);
418
419                subNode = subNode->next;
420            }
421        } else {
422            if (definition.children.size() > 0) {
423                dodoMap<dodo::string, __definition__>::const_iterator i(definition.children.begin()), j(definition.children.end());
424                for (; i != j; ++i)
425                    n.nodeChildren.insert(std::make_pair(i->first, parse(i->second, xnode->children)));
426            }
427        }
428
429        nArr.push_back(n);
430
431        xnode = xnode->next;
432    }
433#endif
434
435    return nArr;
436}
437
438//-------------------------------------------------------------------
439
440void
441#if defined(LIBXML2_EXT)
442processor::getAttributes(const __definition__ &definition,
443                         const __node__       &xnode,
444                         dodoStringMap        &attributes)
445#else
446processor::getAttributes(const __definition__ &definition UNUSED,
447                         const __node__       &xnode UNUSED,
448                         dodoStringMap        &attributes UNUSED)
449#endif
450{
451#ifdef LIBXML2_EXT
452    xmlAttrPtr attribute = xnode.node->properties;
453
454    if (definition.allAttributes) {
455        while (attribute != NULL) {
456            unsigned char *xChar = xmlGetProp(xnode.node, attribute->name);
457            if (xChar != NULL) {
458                attributes[(char *)attribute->name] = (char *)xChar;
459                xmlFree(xChar);
460            }
461
462            attribute = attribute->next;
463        }
464    } else {
465        if (definition.attributes.size() > 0) {
466            dodoStringArray::const_iterator jAttr = definition.attributes.end();
467            if (icaseNames) {
468                while (attribute != NULL) {
469                    dodoStringArray::const_iterator iAttr = definition.attributes.begin();
470                    for (; iAttr != jAttr; ++iAttr) {
471                        if (xmlStrcmp(attribute->name, (unsigned char *)iAttr->data()) == 0) {
472                            unsigned char *xChar = xmlGetProp(xnode.node, attribute->name);
473                            if (xChar != NULL) {
474                                attributes[*iAttr] = (char *)xChar;
475                                xmlFree(xChar);
476                            }
477                        }
478                    }
479
480                    attribute = attribute->next;
481                }
482            } else {
483                dodoStringArray::const_iterator iAttr = definition.attributes.begin();
484                for (; iAttr != jAttr; ++iAttr) {
485                    unsigned char *xChar = xmlGetProp(xnode.node, (unsigned char *)iAttr->data());
486                    if (xChar != NULL) {
487                        attributes[*iAttr] = (char *)xChar;
488                        xmlFree(xChar);
489                    }
490                }
491            }
492        }
493    }
494#endif
495}
496
497//-------------------------------------------------------------------
498
499void
500#if defined(LIBXML2_EXT)
501processor::getAttributes(const __node__ &xnode,
502                         dodoStringMap  &attributes)
503#else
504processor::getAttributes(const __node__ &xnode UNUSED,
505                         dodoStringMap  &attributes UNUSED)
506#endif
507{
508#ifdef LIBXML2_EXT
509    xmlAttrPtr attribute = xnode.node->properties;
510
511    while (attribute != NULL) {
512        unsigned char *xChar = xmlGetProp(xnode.node, attribute->name);
513        if (xChar != NULL) {
514            attributes[(char *)attribute->name] = (char *)xChar;
515            xmlFree(xChar);
516        }
517
518        attribute = attribute->next;
519    }
520#endif
521}
522
523//-------------------------------------------------------------------
524
525void
526#if defined(LIBXML2_EXT)
527processor::getNode(const __node__ &xnode,
528                   node           &resNode)
529#else
530processor::getNode(const __node__ &xnode UNUSED,
531                   node           &resNode UNUSED)
532#endif
533{
534#ifdef LIBXML2_EXT
535    if (xnode.node->ns != NULL) {
536        resNode.ns.prefix = (char *)xnode.node->ns->prefix;
537        resNode.ns.href = (char *)xnode.node->ns->href;
538    }
539
540    if (xnode.node->nsDef != NULL) {
541        resNode.nsDef.prefix = (char *)xnode.node->nsDef->prefix;
542        resNode.nsDef.href = (char *)xnode.node->nsDef->href;
543    }
544
545    if (xnode.node->name != NULL)
546        resNode.name = (char *)xnode.node->name;
547
548    unsigned char *xChar = xmlNodeListGetString(document->doc, xnode.node->children, 1);
549    if (xChar != NULL) {
550        resNode.nodeValue = (char *)xChar;
551        xmlFree(xChar);
552    }
553#endif
554}
555
556//-------------------------------------------------------------------
557
558__info__
559processor::information()
560{
561    return info;
562}
563
564//-------------------------------------------------------------------
565
566dodoArray<node>
567#if defined(LIBXML2_EXT)
568processor::parse(__node__ xnode)
569#else
570processor::parse(__node__ xnode UNUSED)
571#endif
572{
573    dodoArray<node> nArr;
574
575#ifdef LIBXML2_EXT
576    node _n;
577
578    dodoArray<node> children;
579    dodoArray<node>::iterator i, j;
580
581    while (xnode.node != NULL) {
582        if (xnode.node->type != XML_ELEMENT_NODE) {
583            xnode.node = xnode.node->next;
584
585            continue;
586        }
587
588        getNode(xnode, _n);
589
590        getAttributes(xnode, _n.attributes);
591
592        _n.CDATA = isCDATA(xnode);
593
594        if (xnode.node->children != NULL) {
595            children = parse(__node__(xnode.node->children));
596            i = children.begin();
597            j = children.end();
598            for (; i != j; ++i)
599                _n.nodeChildren[i->name].push_back(*i);
600        }
601
602        nArr.push_back(_n);
603
604        initNode(_n);
605
606        xnode.node = xnode.node->next;
607    }
608#endif
609
610    return nArr;
611}
612
613//-------------------------------------------------------------------
614
615void
616processor::initNode(node &xnode)
617{
618    xnode.attributes.clear();
619    xnode.nodeChildren.clear();
620    xnode.name.clear();
621    xnode.ns.prefix.clear();
622    xnode.ns.href.clear();
623    xnode.nsDef.prefix.clear();
624    xnode.nsDef.href.clear();
625    xnode.nodeValue.clear();
626}
627
628//-------------------------------------------------------------------
629
630node
631processor::process(const io::channel &io)
632{
633#ifdef LIBXML2_EXT
634    xmlFreeDoc(document->doc);
635#endif
636
637    node n;
638
639    dodo::string buffer, bufferPart;
640    while (true) {
641        bufferPart = io.readString();
642        if (bufferPart.size() == 0)
643            break;
644
645        buffer += bufferPart;
646    }
647    bufferPart.clear();
648
649#ifdef LIBXML2_EXT
650    document->doc = xmlParseMemory(buffer.data(), buffer.size());
651    if (document->doc == NULL) {
652        xmlErrorPtr error = xmlGetLastError();
653
654        if (error == NULL)
655            dodo_throw exception::basic(exception::MODULE_DATAFORMATXMLPROCESSOR, PROCESSOREX_PARSEBUFFER, exception::ERRNO_LIBDODO, PROCESSOREX_EMPTYDOCUMENT, DATAFORMATXMLPROCESSOREX_EMPTYDOCUMENT_STR, __LINE__, __FILE__);
656        else
657            dodo_throw exception::basic(exception::MODULE_DATAFORMATXMLPROCESSOR, PROCESSOREX_PARSEBUFFER, exception::ERRNO_LIBXML2, error->code, error->message, __LINE__, __FILE__);
658    }
659
660    info = __info__(document->doc->version != NULL ? (char *)document->doc->version : __dodostring__,
661                    document->doc->encoding != NULL ? (char *)document->doc->encoding : __dodostring__,
662                    (document->doc->children != NULL && document->doc->children->name != NULL) ? (char *)document->doc->children->name : __dodostring__,
663                    document->doc->compression);
664
665
666    xmlNodePtr xnode = xmlDocGetRootElement(document->doc);
667    if (xnode == NULL) {
668        xmlErrorPtr error = xmlGetLastError();
669
670        if (error == NULL)
671            dodo_throw exception::basic(exception::MODULE_DATAFORMATXMLPROCESSOR, PROCESSOREX_PARSEBUFFER, exception::ERRNO_LIBDODO, PROCESSOREX_NOROOTNODE, DATAFORMATXMLPROCESSOREX_NOROOTNODE_STR, __LINE__, __FILE__);
672        else
673            dodo_throw exception::basic(exception::MODULE_DATAFORMATXMLPROCESSOR, PROCESSOREX_PARSEBUFFER, exception::ERRNO_LIBXML2, error->code, error->message, __LINE__, __FILE__);
674    }
675
676    n = *(parse(__node__(xnode)).begin());
677#endif
678
679    return n;
680}
681
682//-------------------------------------------------------------------
683
684__node__
685#if defined(LIBXML2_EXT)
686processor::findNode(const __definition__ &definition,
687                    const __node__       &node)
688#else
689processor::findNode(const __definition__ &definition UNUSED,
690                    const __node__       &node UNUSED)
691#endif
692{
693#ifdef LIBXML2_EXT
694    xmlNodePtr _n, xnode = node.node;
695    bool skip;
696
697    strCmp cmpFunc = icaseNames ? xmlStrcasecmp : xmlStrcmp;
698
699    while (xnode != NULL) {
700        if (xnode->type != XML_ELEMENT_NODE) {
701            xnode = xnode->next;
702
703            continue;
704        }
705
706        skip = false;
707
708        if (definition.ns.size() > 0) {
709            if (xnode->ns == NULL)
710                skip = true;
711            else if (cmpFunc(xnode->ns->prefix, (unsigned char *)definition.ns.data()) != 0)
712                skip = true;
713        }
714
715        if (!skip && xnode->name != NULL)
716            if (cmpFunc(xnode->name, (unsigned char *)definition.name.data()) == 0)
717                return xnode;
718
719        _n = findNode(definition, __node__(xnode->children)).node;
720
721        if (_n != NULL)
722            return _n;
723
724        xnode = xnode->next;
725    }
726
727    return __node__(NULL);
728#else
729    return __node__();
730#endif
731}
732
733//-------------------------------------------------------------------
734
735void
736processor::clear()
737{
738#ifdef LIBXML2_EXT
739    xmlFreeDoc(document->doc);
740    document->doc = NULL;
741#endif
742}
743
744//-------------------------------------------------------------------
745
746void
747processor::make(const node        &root,
748                const dodo::string  &encoding,
749                const dodo::string  &version,
750                const io::channel &io) const
751{
752    if (root.name.empty())
753        dodo_throw exception::basic(exception::MODULE_DATAFORMATXMLPROCESSOR, PROCESSOREX_MAKE, exception::ERRNO_LIBDODO, PROCESSOREX_NONAME, DATAFORMATXMLPROCESSOREX_NONAME_STR, __LINE__, __FILE__);
754
755    io.writeString("<?xml version=\"");
756    io.writeString(version);
757    io.writeString("\" encoding=\"");
758    io.writeString(encoding);
759    io.writeString("\"?>\r\n");
760
761    make(root, io);
762}
763
764//-------------------------------------------------------------------
765
766void
767processor::make(const node        &xnode,
768                const io::channel &io) const
769{
770    if (xnode.name.empty())
771        dodo_throw exception::basic(exception::MODULE_DATAFORMATXMLPROCESSOR, PROCESSOREX_MAKE, exception::ERRNO_LIBDODO, PROCESSOREX_NONAME, DATAFORMATXMLPROCESSOREX_NONAME_STR, __LINE__, __FILE__);
772
773    io.writeString(statements[STATEMENT_LT]);
774
775    if (!xnode.ns.prefix.empty()) {
776        io.writeString(xnode.ns.prefix);
777        io.writeString(statements[STATEMENT_COLON]);
778    }
779    io.writeString(xnode.name);
780
781    if (!xnode.nsDef.prefix.empty()) {
782        io.writeString(statements[STATEMENT_SPACE]);
783        io.writeString(statements[STATEMENT_XMLNS]);
784        io.writeString(xnode.nsDef.prefix);
785        io.writeString(statements[STATEMENT_EQUALDQUOTE]);
786        io.writeString(xnode.nsDef.href);
787        io.writeString(statements[STATEMENT_DQUOTE]);
788    }
789
790    dodoMap<dodo::string, dodo::string, dodoMapStringCompare>::const_iterator i = xnode.attributes.begin(), j = xnode.attributes.end();
791    for (; i != j; ++i) {
792        io.writeString(statements[STATEMENT_SPACE]);
793        io.writeString(i->first);
794        io.writeString(statements[STATEMENT_EQUALDQUOTE]);
795        io.writeString(i->second);
796        io.writeString(statements[STATEMENT_DQUOTE]);
797    }
798
799    if (xnode.nodeValue.empty() && xnode.nodeChildren.empty()) {
800        io.writeString(statements[STATEMENT_SLASHGT]);
801
802        return;
803    }
804
805    io.writeString(statements[STATEMENT_GT]);
806
807    if (!xnode.nodeValue.empty()) {
808        if (xnode.CDATA) {
809            io.writeString(statements[STATEMENT_CDATAOPEN]);
810            io.writeString(xnode.nodeValue);
811            io.writeString(statements[STATEMENT_CDATACLOSE]);
812        } else
813            io.writeString(xnode.nodeValue);
814    }
815
816    dodoMap<dodo::string, dodoArray<node>, dodoMapStringCompare>::const_iterator o = xnode.nodeChildren.begin(), p = xnode.nodeChildren.end();
817    dodoArray<node>::const_iterator x, y;
818    for (; o != p; ++o) {
819        x = o->second.begin();
820        y = o->second.end();
821        for (; x != y; ++x)
822            make(*x, io);
823    }
824
825    io.writeString(statements[STATEMENT_LTSLASH]);
826
827    if (!xnode.ns.prefix.empty()) {
828        io.writeString(xnode.ns.prefix);
829        io.writeString(statements[STATEMENT_COLON]);
830    }
831
832    io.writeString(xnode.name);
833    io.writeString(statements[STATEMENT_GT]);
834}
835
836//-------------------------------------------------------------------
837
Note: See TracBrowser for help on using the repository browser.