Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkPropertyListsXmlFileReaderAndWriter.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 #include "mitkProperties.h"
16 #include <itksys/SystemTools.hxx>
17 #include <tinyxml.h>
18 
19 namespace mitk
20 {
23  TiXmlElement *elem) const
24  {
25  if (!elem)
26  {
27  return false;
28  }
29 
30  bool readOp = false;
31  std::string type = "";
32  readOp = elem->QueryStringAttribute("type", &type) == TIXML_SUCCESS;
33  if (readOp)
34  readOp = elem->QueryStringAttribute("name", &name) == TIXML_SUCCESS;
35  else
36  MITK_WARN << "type"
37  << " attribute not found in a property";
38 
39  if (readOp)
40  {
41  if (type == "BoolProperty")
42  {
43  int val = 0;
44  readOp = elem->QueryIntAttribute("value", &val) == TIXML_SUCCESS;
45  if (readOp)
46  {
47  prop = mitk::BoolProperty::New(val == 1 ? true : false);
48  }
49  }
50  else if (type == "StringProperty")
51  {
52  std::string val = "";
53  readOp = elem->QueryStringAttribute("value", &val) == TIXML_SUCCESS;
54  if (readOp)
55  {
56  prop = mitk::StringProperty::New(val);
57  }
58  }
59  else if (type == "IntProperty")
60  {
61  int val = 0;
62  readOp = elem->QueryIntAttribute("value", &val) == TIXML_SUCCESS;
63  if (readOp)
64  {
65  prop = mitk::IntProperty::New(val);
66  }
67  }
68  else if (type == "DoubleProperty")
69  {
70  double val = 0;
71  readOp = elem->QueryDoubleAttribute("value", &val) == TIXML_SUCCESS;
72  if (readOp)
73  {
74  prop = mitk::DoubleProperty::New(val);
75  }
76  }
77  else if (type == "FloatProperty")
78  {
79  float val = 0;
80  readOp = elem->QueryFloatAttribute("value", &val) == TIXML_SUCCESS;
81  if (readOp)
82  {
83  prop = mitk::FloatProperty::New(val);
84  }
85  }
86  else
87  {
88  readOp = false;
89  MITK_WARN << "type"
90  << " attribute unknown. Only BoolProperty, StringProperty, IntProperty, DoubleProperty or "
91  "FloatProperty allowed.";
92  }
93  }
94  else
95  MITK_WARN << "name"
96  << " attribute not found in a property";
97 
98  if (!readOp)
99  MITK_WARN << "value"
100  << " attribute not found in a property";
101 
102  return readOp;
103  }
105  const mitk::BaseProperty *prop,
106  TiXmlElement *elem) const
107  {
108  if (!prop || !elem)
109  {
110  return false;
111  }
112 
113  const mitk::IntProperty *intProp = nullptr;
114  const mitk::FloatProperty *floatProp = nullptr;
115  const mitk::DoubleProperty *doubleProp = nullptr;
116  const mitk::BoolProperty *boolProp = nullptr;
117  const mitk::StringProperty *stringProp = nullptr;
118  bool writeOp = true;
119 
120  if ((boolProp = dynamic_cast<const BoolProperty *>(prop)))
121  {
122  elem->SetAttribute(GetPropertyListIdElementName(), name);
123  elem->SetAttribute("value", boolProp->GetValue() ? 1 : 0);
124  elem->SetAttribute("type", "BoolProperty");
125  }
126  else if ((stringProp = dynamic_cast<const StringProperty *>(prop)))
127  {
128  elem->SetAttribute(GetPropertyListIdElementName(), name);
129  elem->SetAttribute("value", stringProp->GetValue());
130  elem->SetAttribute("type", "StringProperty");
131  }
132  else if ((intProp = dynamic_cast<const IntProperty *>(prop)))
133  {
134  elem->SetAttribute(GetPropertyListIdElementName(), name);
135  elem->SetAttribute("value", intProp->GetValue());
136  elem->SetAttribute("type", "IntProperty");
137  }
138  else if ((doubleProp = dynamic_cast<const DoubleProperty *>(prop)))
139  {
140  elem->SetAttribute(GetPropertyListIdElementName(), name);
141  elem->SetDoubleAttribute("value", doubleProp->GetValue());
142  elem->SetAttribute("type", "DoubleProperty");
143  }
144  else if ((floatProp = dynamic_cast<const FloatProperty *>(prop)))
145  {
146  elem->SetAttribute(GetPropertyListIdElementName(), name);
147  elem->SetDoubleAttribute("value", static_cast<float>(floatProp->GetValue()));
148  elem->SetAttribute("type", "FloatProperty");
149  }
150  else
151  {
152  MITK_WARN("PropertyListImportFromXmlFile") << "Base property " << name << " is unknown";
153  writeOp = false;
154  }
155  return writeOp;
156  }
158  const std::string &fileName, const std::map<std::string, mitk::PropertyList::Pointer> &_PropertyLists) const
159  {
160  TiXmlDocument doc;
161 
162  auto decl = new TiXmlDeclaration("1.0", "", "");
163  doc.LinkEndChild(decl);
164  // create root
165  auto propertyListsElem = new TiXmlElement("PropertyLists");
166 
167  bool allPropsConverted = true;
168  auto it = _PropertyLists.begin();
169  while (it != _PropertyLists.end())
170  {
171  const std::string &id = (*it).first;
172  const PropertyList *propList = (*it).second;
173  auto propertyListElem = new TiXmlElement("PropertyList");
174  propertyListElem->SetAttribute(GetPropertyListIdElementName(), id);
175 
176  const std::map<std::string, BaseProperty::Pointer> *propMap = propList->GetMap();
177  auto propMapIt = propMap->begin();
178  while (propMapIt != propMap->end())
179  {
180  const std::string &propName = (*propMapIt).first;
181  const BaseProperty *prop = (*propMapIt).second;
182  auto propertyElem = new TiXmlElement("Property");
183 
184  if (!this->PropertyToXmlElem(propName, prop, propertyElem))
185  allPropsConverted = false;
186 
187  propertyListElem->LinkEndChild(propertyElem);
188  ++propMapIt;
189  }
190 
191  propertyListsElem->LinkEndChild(propertyListElem);
192  ++it;
193  }
194 
195  doc.LinkEndChild(propertyListsElem);
196 
197  return (allPropsConverted && doc.SaveFile(fileName.c_str()));
198  }
200  const std::string &fileName, std::map<std::string, mitk::PropertyList::Pointer> &_PropertyLists) const
201  {
202  // reread
203  TiXmlDocument doc(fileName);
204  doc.LoadFile();
205 
206  TiXmlHandle docHandle(&doc);
207  TiXmlElement *elem = docHandle.FirstChildElement("PropertyLists").FirstChildElement("PropertyList").ToElement();
208 
209  if (!elem)
210  {
211  MITK_WARN("PropertyListFromXml") << "Cannot find a PropertyList element (inside a PropertyLists element)";
212  return false;
213  }
214 
215  bool opRead = false;
216  while (elem)
217  {
218  std::string propListId;
219  opRead = elem->QueryStringAttribute(GetPropertyListIdElementName(), &propListId) == TIXML_SUCCESS;
220  if (!opRead)
221  break;
222 
224 
225  TiXmlElement *propElem = elem->FirstChildElement("Property");
226 
227  while (propElem)
228  {
229  std::string name;
231  opRead = this->PropertyFromXmlElem(name, prop, propElem);
232  if (!opRead)
233  break;
234  propList->SetProperty(name, prop);
235  propElem = propElem->NextSiblingElement("Property");
236  }
237 
238  if (!opRead)
239  break;
240  _PropertyLists[propListId] = propList;
241  elem = elem->NextSiblingElement("PropertyList");
242  }
243 
244  return opRead;
245  }
246 
250 }
static Pointer New()
static Pointer New()
virtual const char * GetValue() const
DataCollection - Class to facilitate loading/accessing structured data.
bool PropertyToXmlElem(const std::string &name, const mitk::BaseProperty *prop, TiXmlElement *elem) const
Key-value list holding instances of BaseProperty.
virtual T GetValue() const
bool ReadLists(const std::string &fileName, std::map< std::string, mitk::PropertyList::Pointer > &_PropertyLists) const
static Pointer New()
Abstract base class for properties.
#define MITK_WARN
Definition: mitkLogMacros.h:19
static Pointer New()
static Pointer New()
bool WriteLists(const std::string &fileName, const std::map< std::string, mitk::PropertyList::Pointer > &_PropertyLists) const
bool PropertyFromXmlElem(std::string &name, mitk::BaseProperty::Pointer &prop, TiXmlElement *elem) const
Property for strings.
static Pointer New()
const PropertyMap * GetMap() const