Shapeworks Studio  2.1
Shape analysis software suite
itkPSMDOMNodeXMLReader.cxx
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 
19 #include "itkPSMDOMNodeXMLReader.h"
20 #include "expat.h"
21 
22 #include <fstream>
23 
24 namespace itk
25 {
26 
32 static void itkXMLParserStartElement( void* parser, const char* name, const char** atts )
33 {
34  // Begin element handler that is registered with the XML_Parser.
35  // This just casts the user data to a itkXMLParser and calls
36  // StartElement.
37  static_cast<PSMDOMNodeXMLReader*>(parser)->StartElement( name, atts );
38 }
39 
40 static void itkXMLParserEndElement( void* parser, const char* name )
41 {
42  // End element handler that is registered with the XML_Parser. This
43  // just casts the user data to a itkXMLParser and calls EndElement.
44  static_cast<PSMDOMNodeXMLReader*>(parser)->EndElement( name );
45 }
46 
47 static void itkXMLParserCharacterDataHandler( void* parser, const char* data, int length )
48 {
49  // Character data handler that is registered with the XML_Parser.
50  // This just casts the user data to a itkXMLParser and calls
51  // CharacterDataHandler.
52  static_cast<PSMDOMNodeXMLReader*>(parser)->CharacterDataHandler( data, length );
53 }
54 
55 PSMDOMNodeXMLReader::PSMDOMNodeXMLReader() : m_Context(NULL)
56 {
57 }
58 
63 void
64 PSMDOMNodeXMLReader::Update( std::istream& is )
65 {
66  DOMNodeType* output = this->GetDOMNode();
67  if ( output == NULL )
68  {
69  DOMNodePointer object = DOMNodeType::New();
70  output = (DOMNodeType*)object;
71  this->SetDOMNode( output );
72  }
73 
74  output->RemoveAllAttributesAndChildren();
75  this->m_Context = NULL;
76 
77  is >> std::noskipws;
78  std::string s;
79  while ( true )
80  {
81  char c = 0;
82  is >> c;
83  if ( !is.good() )
84  {
85  break;
86  }
87  s.append( 1, c );
88  }
89 
90  XML_Parser parser = XML_ParserCreate( 0 );
91  XML_SetElementHandler( parser, &itkXMLParserStartElement, &itkXMLParserEndElement );
92  XML_SetCharacterDataHandler( parser, &itkXMLParserCharacterDataHandler );
93  XML_SetUserData( parser, this );
94 
95  bool ok = XML_Parse( parser, s.data(), s.size(), false );
96  if ( !ok )
97  {
98  ExceptionObject e( __FILE__, __LINE__ );
99  std::string message( XML_ErrorString(XML_GetErrorCode(parser)) );
100  e.SetDescription( message.c_str() );
101  throw e;
102  }
103 
104  XML_ParserFree( parser );
105 }
106 
110 void
112 {
113  std::ifstream is( this->m_FileName.c_str() );
114  if ( !is.is_open() )
115  {
116  itkExceptionMacro( "failed openning the input XML file" );
117  }
118 
119  this->Update( is );
120 
121  is.close();
122 }
123 
127 void
128 PSMDOMNodeXMLReader::StartElement( const char* name, const char** atts )
129 {
130  DOMNodeType* node = NULL;
131  if ( this->m_Context )
132  {
133  DOMNodePointer node1 = DOMNodeType::New();
134  node = (DOMNodeType*)node1;
135  this->m_Context->AddChildAtEnd( node );
136  }
137  else
138  {
139  node = this->GetDOMNode();
140  }
141  node->SetName( name );
142 
143  size_t i = 0;
144  while ( atts[i] )
145  {
146  std::string key( atts[i++] );
147  std::string value( atts[i++] );
148  if ( StringTools::MatchWith(key,"id") )
149  {
150  node->SetID( value );
151  }
152  else
153  {
154  node->SetAttribute( key, value );
155  }
156  }
157 
158  this->m_Context = node;
159 }
160 
164 void
166 {
167  if ( this->m_Context->GetName() != name )
168  {
169  itkExceptionMacro( "start/end tag names mismatch" );
170  }
171  this->m_Context = dynamic_cast<PSMDOMNode *>(this->m_Context->GetParent());
172 }
173 
177 void
178 PSMDOMNodeXMLReader::CharacterDataHandler( const char* text, int len )
179 {
180  std::string s( text, len );
181 
182  StringTools::Trim( s );
183  if ( s.size() == 0 )
184  {
185  return;
186  }
187 
188  this->m_Context->AddText(s);
189 }
190 
191 } // namespace itk
virtual void CharacterDataHandler(const char *text, int len)
Class to represent a node in the PSM Document Object Model (DOM) tree structure.
Definition: itkPSMDOMNode.h:46
virtual void EndElement(const char *name)
virtual void StartElement(const char *name, const char **atts)