Project

General

Profile

Statistics
| Branch: | Revision:

root / src / nedxml / xmlgenerator.cc @ c87b95b0

History | View | Annotate | Download (4.03 KB)

1
//==========================================================================
2
//  XMLGENERATOR.CC - part of
3
//
4
//                     OMNeT++/OMNEST
5
//            Discrete System Simulation in C++
6
//
7
//==========================================================================
8

    
9
/*--------------------------------------------------------------*
10
  Copyright (C) 2002-2008 Andras Varga
11
  Copyright (C) 2006-2008 OpenSim Ltd.
12

13
  This file is distributed WITHOUT ANY WARRANTY. See the file
14
  `terms' for details on this and other legal matters.
15
*--------------------------------------------------------------*/
16

    
17

    
18
#include <string.h>
19
#include <sstream>
20
#include <iostream>
21
#include <iomanip>
22
#include "nedelements.h"
23
#include "xmlgenerator.h"
24

    
25
NAMESPACE_BEGIN
26

    
27
using std::ostream;
28
using std::endl;
29

    
30
void generateXML(ostream& out, NEDElement *tree, bool srcloc, int indentsize)
31
{
32
    NEDXMLGenerator xmlgen;
33
    xmlgen.setIndentSize(indentsize);
34
    xmlgen.setSourceLocationAttributes(srcloc);
35
    xmlgen.generate(out, tree);
36
}
37

    
38
std::string generateXML(NEDElement *tree, bool srcloc, int indentsize)
39
{
40
    std::stringstream out;
41
    generateXML(out, tree, srcloc, indentsize);
42
    return out.str();
43
}
44

    
45
//-----------------------------------------
46

    
47
NEDXMLGenerator::NEDXMLGenerator()
48
{
49
    indentsize = 2;
50
}
51

    
52
NEDXMLGenerator::~NEDXMLGenerator()
53
{
54
}
55

    
56
void NEDXMLGenerator::setSourceLocationAttributes(bool srcloc)
57
{
58
    printsrcloc = srcloc;
59
}
60

    
61
void NEDXMLGenerator::setIndentSize(int indentsiz)
62
{
63
    indentsize = indentsiz;
64
    if (indentsize>16) indentsize=16;
65
}
66

    
67
void NEDXMLGenerator::generate(ostream& out, NEDElement *tree)
68
{
69
    // xml header
70
    out << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" << endl << endl;
71

    
72
    // recursively generate children
73
    doGenerate(out, tree, 0);
74
}
75

    
76
std::string NEDXMLGenerator::generate(NEDElement *tree)
77
{
78
    std::stringstream out;
79
    generate(out, tree);
80
    return out.str();
81
}
82

    
83
void NEDXMLGenerator::printAttrValue(ostream& out, const char *s)
84
{
85
    for (; *s; s++)
86
    {
87
        unsigned char c = *s;
88
        if (c=='<')
89
           out << "&lt;";
90
        else if (c=='>')
91
           out << "&gt;";
92
        else if (c=='"')
93
           out << "&quot;";
94
        else if (c=='&')
95
           out << "&amp;";
96
        else if (c<32)
97
           out << "&#" << int(c) << ";";
98
        else
99
           out << c;
100
    }
101
}
102

    
103
void NEDXMLGenerator::doGenerate(ostream& out, NEDElement *node, int level)
104
{
105
    const char *indent = "                ";
106
    indent = indent + strlen(indent) - indentsize;
107

    
108
    // indent + opening tag
109
    int i;
110
    for (i=0; i<level; i++)
111
        out << indent;
112
    out << "<" << node->getTagName();
113

    
114
    // location info
115
    if (printsrcloc && node->getSourceLocation())
116
    {
117
        out << " src-loc=\"";
118
        printAttrValue(out, node->getSourceLocation());
119
        out << "\"";
120

    
121
        const NEDSourceRegion& r = node->getSourceRegion();
122
        if (r.startLine>0) // filled in
123
        {
124
            out << " src-region=\"" << r.startLine << ":" << r.startColumn << "-"
125
                << r.endLine << ":" << r.endColumn << "\"";
126
        }
127
    }
128

    
129
    // output attributes, but only if they differ from their default values
130
    for (i=0; i<node->getNumAttributes(); i++)
131
    {
132
        const char *attrval = node->getAttribute(i);
133
        const char *defaultval = node->getAttributeDefault(i);
134
        if (!attrval) attrval = "";
135
        if (!defaultval) defaultval= "";
136
        if (strcmp(attrval,defaultval))
137
        {
138
            out << " " << node->getAttributeName(i);
139
            out << "=\"";
140
            printAttrValue(out, attrval);
141
            out << "\"";
142
        }
143
    }
144

    
145
    // if no children, merge closing tag using "<../>"
146
    if (!node->getFirstChild())
147
    {
148
       out << "/>" << endl;
149
       return;
150
    }
151
    out << ">" << endl;
152

    
153
    // children
154
    for (NEDElement *child=node->getFirstChild(); child; child=child->getNextSibling())
155
    {
156
        doGenerate(out, child, level+1);
157
    }
158

    
159
    // indent + closing tag
160
    for (i=0; i<level; i++)
161
        out << indent;
162
    out << "</" << node->getTagName() << ">" << endl;
163
}
164

    
165
NAMESPACE_END
166

    
167