Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
969 runge 1
/***************************************************************************
2
 *   Copyright (C) November 30, 2008 by Mattias Runge                             *
3
 *   mattias@runge.se                                                      *
4
 *   xmlnode.cpp                                            *
5
 *                                                                         *
6
 *   This program is free software; you can redistribute it and/or modify  *
7
 *   it under the terms of the GNU General Public License as published by  *
8
 *   the Free Software Foundation; either version 2 of the License, or     *
9
 *   (at your option) any later version.                                   *
10
 *                                                                         *
11
 *   This program is distributed in the hope that it will be useful,       *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU General Public License for more details.                          *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU General Public License     *
17
 *   along with this program; if not, write to the                         *
18
 *   Free Software Foundation, Inc.,                                       *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20
 ***************************************************************************/
21
 
22
#include "xmlnode.h"
23
 
24
void XmlNode::load(string filename)
25
{
26
    parse(file_get_contents(filename));
27
}
28
 
29
void XmlNode::parse(string xmlData)
30
{
31
    char c;
32
    int position = 0;
33
    while (position < xmlData.length())
34
    {
35
        c = xmlData.at(position);
36
 
37
        switch (c)
38
        {
39
            case '<':
40
                position = parseTag(xmlData, position);
41
                break;
42
        }
43
        position++;
44
    }
45
}
46
 
47
int XmlNode::parseTag(string xmlData, int position)
48
{
49
    if (xmlData.at(position) != '<')
50
        throw new XmlException("Did not find < as expected. Character " + itos(position));
51
 
52
    position++;
53
 
54
    int endPosition = xmlData.find('>', position);
55
 
56
    if (xmlData.at(position) == '?' || xmlData.at(position) == '!' || xmlData.at(position) == '/')
57
    {
58
        return endPosition;
59
    }
60
 
61
    string tagString = xmlData.substr(position, endPosition-position);
62
 
63
    tagString = trim(tagString);
64
    tagString = trim(tagString, '\n');
65
    tagString = trim(tagString);
66
    tagString += " ";
67
 
68
    bool foundEnd = false;
69
    bool foundTag = false;
70
    string buffer;
71
    int pos = 0;
72
    char c;
73
    int s, e;
74
 
75
    while (pos < tagString.length())
76
    {
77
        c = tagString.at(pos);
78
 
79
        switch (c)
80
        {
81
            case ' ':
82
                if (!foundTag)
83
                {
84
                    myTagName = buffer;
85
                    buffer = "";
86
                    //cout << "Found tag: " << myTagName << endl;
87
                    foundTag = true;
88
                }
89
                break;
90
 
91
            case '/':
92
                foundEnd = true;
93
                break;
94
 
95
            case '=':
96
                s = tagString.find('"', pos)+1;
97
                e = tagString.find('"', s);
98
 
99
                myAttributes[buffer] = tagString.substr(s, e-s);
100
                //cout << "Found attribute: " << buffer << " = " << myAttributes[buffer] << endl;
101
                pos = e;
102
                buffer = "";
103
                break;
104
 
105
            default:
106
                buffer += c;
107
                break;
108
        }
109
        pos++;
110
    }
111
 
112
    position = endPosition;
113
 
114
    if (!foundEnd)
115
    {
116
        while (position < xmlData.length())
117
        {
118
            c = xmlData.at(position);
119
 
120
            switch (c)
121
            {
122
                case '<':
123
                    if (xmlData.at(position+1) == '/')
124
                    {
125
                        position += 2;
126
                        endPosition = xmlData.find('>', position);
127
 
128
                        if (myTagName.compare(xmlData.substr(position, endPosition-position)) == 0)
129
                        {
130
                            //cout << "Found end tag: " << myTagName << endl;
131
                            return endPosition;
132
                        }
133
                        else
134
                        {
135
                            throw new XmlException("Invalid end tag found. " + xmlData.substr(position, endPosition-position) + "::" + myTagName);
136
                        }
137
                    }
138
 
139
                    XmlNode subNode;
140
                    position = subNode.parseTag(xmlData, position);
141
                    myChildren.push_back(subNode);
142
                    break;
143
            }
144
 
145
            position++;
146
        }
147
    }
148
 
149
    return position;
150
}
151
 
152
XmlNode XmlNode::findChild(string tagName)
153
{
154
    for (int n = 0; n < myChildren.size(); n++)
155
    {
156
        if (myChildren[n].getTagName().compare(tagName) == 0)
157
            return myChildren[n];
158
    }
159
 
160
    XmlNode defaultNode;
161
 
162
    return defaultNode;
163
}
164
 
165
string XmlNode::getAttributeValue(string attributeName)
166
{
167
    map<string, string>::const_iterator iterator = myAttributes.find(attributeName);
168
 
169
    if (iterator == myAttributes.end())
170
        return NULL;
171
 
172
    return iterator->second;
173
}