MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkXMLSerializable.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12#include <mitkXMLSerializable.h>
13#include "mitkEndoDebug.h"
14#include "mitkEndoMacros.h"
15#include <itksys/SystemTools.hxx>
16#include <tinyxml2.h>
17
18namespace mitk
19{
20 const std::string XMLSerializable::FILE_REFERENCE_ATTRIBUTE_NAME = "fileRef";
21 const std::string XMLSerializable::ROOT_NAME = "data";
22
23 void mitk::XMLSerializable::ToXMLFile(const std::string& file
24 , const std::string& elemName)
25 {
26 tinyxml2::XMLElement * rootElem=nullptr;
27 tinyxml2::XMLElement* element=nullptr;
28
29 // determine element to write to
30 std::string elementName = elemName;
31 if(elementName.empty())
32 elementName = this->GetNameOfClass();
33
34 tinyxml2::XMLDocument doc;
35 // if the document already exists ...
36 if(tinyxml2::XML_SUCCESS == doc.LoadFile(file.c_str()))
37 {
38 // try to identify the XML element of this class as the root
39 // or as the child of the root
40 rootElem = doc.RootElement();
41 endoAssertMsg( rootElem, "No root element found in " << file );
42
43 // if root element represents this element remove the root
44 if( std::string(rootElem->Value() != nullptr ? rootElem->Value() : "") == elementName )
45 {
46 doc.DeleteChild(rootElem);
47 rootElem = nullptr;
48 }
49 else
50 {
51 // if it is a child of the root remove it too
52 element = rootElem->FirstChildElement(elementName.c_str());
53 if(element)
54 rootElem->DeleteChild(element);
55 }
56 }
57 else
58 {
59 // document did not exist, create new one with declration
60 doc.InsertEndChild( doc.NewDeclaration() );
61 }
62
63 m_XMLFileName = file;
64
65 // create element (if the document already exists this element was removed)
66 element = doc.NewElement( elementName.c_str() );
67 this->ToXML( element );
68
69 // if we do not have a root element create a new one
70 if(!rootElem)
71 rootElem = doc.NewElement( ROOT_NAME.c_str() );
72 // add the element node as child
73 rootElem->InsertEndChild(element);
74
75 // if no root element exists, add it now
76 if(doc.RootElement() == nullptr)
77 doc.InsertEndChild( rootElem );
78
79 if(tinyxml2::XML_SUCCESS != doc.SaveFile( file.c_str() ))
80 {
81 std::ostringstream s; s << "File " << file
82 << " could not be written. Please check permissions.";
83 throw std::logic_error(s.str());
84 }
85 }
86
88 {
89 return m_XMLFileName;
90 }
91
92 void mitk::XMLSerializable::FromXMLFile(const std::string& file
93 , const std::string& elemName)
94 {
95 endodebug( "Trying to read from " << file )
96
97 tinyxml2::XMLDocument doc;
98 if(tinyxml2::XML_SUCCESS != doc.LoadFile(file.c_str()))
99 {
100 std::ostringstream s; s << "File " << file
101 << " could not be loaded!";
102 throw std::logic_error(s.str().c_str());
103 }
104
105 m_XMLFileName = file;
106
107 auto* elem = doc.FirstChildElement();
108 endoAssertMsg( elem, "No root element found" );
109
110 // determine element to read from
111 std::string elementName = elemName;
112 if(elementName.empty())
113 elementName = this->GetNameOfClass();
114 // try again with the first element
115 if(strcmp(elem->Value(), elementName.c_str()) != 0)
116 elem = elem->FirstChildElement(elementName.c_str());
117
118 endoAssertMsg( elem, "No child element \"" << elementName <<
119 "\" found in " << file );
120
121 // if theres an attribute as file reference try to load the class
122 // from that file
123 const char* filenameC = elem->Attribute(FILE_REFERENCE_ATTRIBUTE_NAME.c_str());
124 std::string filename = nullptr != filenameC
125 ? filenameC
126 : "";
127 if(!filename.empty())
128 {
129 if( !itksys::SystemTools::FileIsFullPath(filename.c_str()) )
130 filename = itksys::SystemTools::GetFilenamePath(file) + "/" + filename;
131 this->FromXMLFile(filename);
132 return; // exit!
133 }
134
135 this->FromXML( elem );
136 }
137}
virtual void ToXMLFile(const std::string &file, const std::string &elemName="")
static const std::string ROOT_NAME
virtual void FromXMLFile(const std::string &file, const std::string &elemName="")
std::string GetXMLFileName() const
static const std::string FILE_REFERENCE_ATTRIBUTE_NAME
#define endoAssertMsg(a, msg)
#define endodebug(msg)
IGT Exceptions.
int strcmp(const String &s1, const String &s2)
Definition relates.cpp:14