blob: d45f3608f3dedc36d003e8e55c80cca8c2bbb641 [file] [log] [blame]
Kevin Rocard93250d12012-07-19 17:48:30 +02001/*
David Wagnerb76c9d62014-02-05 18:30:24 +01002 * Copyright (c) 2011-2014, Intel Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software without
17 * specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Patrick Benavoli68a91282011-08-31 11:23:23 +020029 */
30#include "XmlElement.h"
31#include <libxml/tree.h>
32#include <stdlib.h>
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020033#include <sstream>
Patrick Benavoli68a91282011-08-31 11:23:23 +020034
Sebastien Gonzalved9526492014-02-20 22:28:03 +010035using std::string;
36using std::ostringstream;
37
Patrick Benavoli68a91282011-08-31 11:23:23 +020038CXmlElement::CXmlElement(_xmlNode* pXmlElement) : _pXmlElement(pXmlElement)
39{
40}
41
42CXmlElement::CXmlElement() : _pXmlElement(NULL)
43{
44}
45
46void CXmlElement::setXmlElement(_xmlNode* pXmlElement)
47{
48 _pXmlElement = pXmlElement;
49}
50
51string CXmlElement::getType() const
52{
53 return (const char*)_pXmlElement->name;
54}
55
56string CXmlElement::getPath() const
57{
58 string strPathElement = "/" + getType();
59
60 if (hasAttribute("Name")) {
61
62 strPathElement += "[@Name=" + getNameAttribute() + "]";
63 }
64
65 CXmlElement parentElement;
66
67 if (getParentElement(parentElement)) {
68
69 // Done
70 return parentElement.getPath() + strPathElement;
71 }
72 return strPathElement;
73}
74
75string CXmlElement::getNameAttribute() const
76{
77 return getAttributeString("Name");
78}
79
80bool CXmlElement::hasAttribute(const string& strAttributeName) const
81{
82 return xmlHasProp(_pXmlElement, (const xmlChar*)strAttributeName.c_str()) != NULL;
83}
84
85string CXmlElement::getAttributeString(const string &strAttributeName) const
86{
87 if (!hasAttribute(strAttributeName)) {
88
89 return "";
90 }
91 xmlChar* pucXmlValue = xmlGetProp((xmlNode*)_pXmlElement, (const xmlChar*)strAttributeName.c_str());
Eduardo Mendi30095b32014-04-15 17:29:52 +020092 if (pucXmlValue == NULL) {
93 return "";
94 }
Patrick Benavoli68a91282011-08-31 11:23:23 +020095
96 string strValue((const char*)pucXmlValue);
97
98 xmlFree(pucXmlValue);
99
100 return strValue;
101}
102
103bool CXmlElement::getAttributeBoolean(const string& strAttributeName, const string& strTrueValue) const
104{
105 return getAttributeString(strAttributeName) == strTrueValue;
106}
107
108bool CXmlElement::getAttributeBoolean(const string& strAttributeName) const
109{
110 string strAttributeValue(getAttributeString(strAttributeName));
111
112 return strAttributeValue == "true" || strAttributeValue == "1";
113}
114
115uint32_t CXmlElement::getAttributeInteger(const string &strAttributeName) const
116{
117 string strAttributeValue(getAttributeString(strAttributeName));
118
119 return strtoul(strAttributeValue.c_str(), NULL, 0);
120}
121
122int32_t CXmlElement::getAttributeSignedInteger(const string &strAttributeName) const
123{
124 string strAttributeValue(getAttributeString(strAttributeName));
125
126 return strtol(strAttributeValue.c_str(), NULL, 0);
127}
128
129double CXmlElement::getAttributeDouble(const string &strAttributeName) const
130{
131 string strAttributeValue(getAttributeString(strAttributeName));
132
133 return strtod(strAttributeValue.c_str(), NULL);
134}
135
136string CXmlElement::getTextContent() const
137{
138 xmlChar* pucXmlContent = xmlNodeGetContent(_pXmlElement);
Eduardo Mendi30095b32014-04-15 17:29:52 +0200139 if (pucXmlContent == NULL) {
140 return "";
141 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200142
143 string strContent((const char*)pucXmlContent);
144
145 xmlFree(pucXmlContent);
146
147 return strContent;
148}
149
150bool CXmlElement::getChildElement(const string& strType, CXmlElement& childElement) const
151{
152 CChildIterator childIterator(*this);
153
154 while (childIterator.next(childElement)) {
155
156 if (childElement.getType() == strType) {
157
158 return true;
159 }
160 }
161 return false;
162}
163
164bool CXmlElement::getChildElement(const string& strType, const string& strNameAttribute, CXmlElement& childElement) const
165{
166 CChildIterator childIterator(*this);
167
168 while (childIterator.next(childElement)) {
169
170 if ((childElement.getType() == strType) && (childElement.getNameAttribute() == strNameAttribute)) {
171
172 return true;
173 }
174 }
175 return false;
176}
177
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200178uint32_t CXmlElement::getNbChildElements() const
179{
180 CXmlElement childElement;
181 uint32_t uiNbChildren = 0;
182
183 CChildIterator childIterator(*this);
184
185 while (childIterator.next(childElement)) {
186
187 uiNbChildren++;
188 }
189 return uiNbChildren;
190}
191
Patrick Benavoli68a91282011-08-31 11:23:23 +0200192bool CXmlElement::getParentElement(CXmlElement& parentElement) const
193{
194 _xmlNode* pXmlNode = _pXmlElement->parent;
195
196 if (pXmlNode->type == XML_ELEMENT_NODE) {
197
198 parentElement.setXmlElement(pXmlNode);
199
200 return true;
201 }
202 return false;
203}
204
205// Setters
Patrick Benavoli63499d42011-10-24 18:50:03 +0200206void CXmlElement::setAttributeBoolean(const string& strAttributeName, bool bValue)
207{
208 setAttributeString(strAttributeName, bValue ? "true" : "false");
209}
210
211
Patrick Benavoli68a91282011-08-31 11:23:23 +0200212void CXmlElement::setAttributeString(const string& strAttributeName, const string& strValue)
213{
214 xmlNewProp(_pXmlElement, BAD_CAST strAttributeName.c_str(), BAD_CAST strValue.c_str());
215}
216
Georges-Henri Baron326a31d2012-06-28 12:05:09 +0200217void CXmlElement::setAttributeInteger(const string& strAttributeName, uint32_t uiValue)
218{
219 ostringstream strStream;
220 strStream << uiValue;
221 setAttributeString(strAttributeName, strStream.str());
222}
223
Patrick Benavoli05485232014-07-08 14:09:09 +0200224void CXmlElement::setAttributeSignedInteger(const string& strAttributeName, int32_t iValue)
225{
226 ostringstream strStream;
227 strStream << iValue;
228 setAttributeString(strAttributeName, strStream.str());
229}
230
Patrick Benavoli68a91282011-08-31 11:23:23 +0200231void CXmlElement::setNameAttribute(const string& strValue)
232{
233 setAttributeString("Name", strValue);
234}
235
236void CXmlElement::setTextContent(const string& strContent)
237{
238 xmlAddChild(_pXmlElement, xmlNewText(BAD_CAST strContent.c_str()));
239}
240
241void CXmlElement::setComment(const string& strComment)
242{
243 xmlAddChild(_pXmlElement, xmlNewComment(BAD_CAST strComment.c_str()));
244}
245
246// Child creation
247void CXmlElement::createChild(CXmlElement& childElement, const string& strType)
248{
249#ifdef LIBXML_TREE_ENABLED
250 xmlNodePtr pChildNode = xmlNewChild(_pXmlElement, NULL, BAD_CAST strType.c_str(), NULL);
251
252 childElement.setXmlElement(pChildNode);
253#endif
254}
255
256// Child iteration
257CXmlElement::CChildIterator::CChildIterator(const CXmlElement& xmlElement) : _pCurNode(xmlElement._pXmlElement->children)
258{
259}
260
261bool CXmlElement::CChildIterator::next(CXmlElement& xmlChildElement)
262{
263 while (_pCurNode) {
264
265 if (_pCurNode->type == XML_ELEMENT_NODE) {
266
267 xmlChildElement.setXmlElement(_pCurNode);
268
269 _pCurNode = _pCurNode->next;
270
271 return true;
272 }
273 _pCurNode = _pCurNode->next;
274 }
275
276 return false;
277}
278