Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
Fox_sax_EQuUs.f90
Go to the documentation of this file.
1 !======================================================================
2 ! Wrapper module to read in the CMLComp XML file generated by the SIESTA package.
3 ! This file is part of the EQuUs package. (for details see: http://eqt.elte.hu/equus/home)
4 ! Copyright (C) 2016 Peter Rakyta, Ph.D.
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 3 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, see http://www.gnu.org/licenses/.
18 !
19 !======================================================================
20 #ifndef MAX_PROP_LENGTH
21 #define MAX_PROP_LENGTH 100
22 #endif
23 
24 
25 
27 
28  use equus_c
29  use fox_sax
30  use equus_xml
31 
32 ! Derived type holding the XML parser
33  type(xml_t), private :: xp
34 ! The number of the retrived nodes
35  integer :: numtargetnodes
36 ! The array of the retrived XML target nodes
37  TYPE(xmlnode), pointer :: targetnodes(:)
38 ! The representation of the current XML target node in focus
39  TYPE(xmlnode), pointer :: currenttargetnode
40 ! The representation of the XML node in focus
41  TYPE(xmlnode), pointer :: currentnode
42 ! Logical value. True if a desired XML node is in focus
43  logical, private :: targetnodeactive = .false.
44 ! The level of the current node in the XML tree
45  integer, private :: subnodelevel = 0
46 ! The local names of the properties to be retrived from the XML
47  character(len=MAX_PROP_LENGTH, kind=C_CHAR), pointer :: property_names(:)
48 
49 
50 
51 !****************************************************************
52  CONTAINS
53 !****************************************************************
54 
55 
56 
57 
58 !-------------------------------------------------------------------------------------------------
59 ! DESCRIPTION:
65  subroutine convertsubnodes2eq_struct( subnodes, XMLsubnodes )
66 
67  TYPE(eqstruct), pointer :: subnodes
68  TYPE(xmlnode), pointer :: XMLsubnodes(:)
69 
70  TYPE(eqstruct), pointer :: eq_struct => null()
71  TYPE(eqelement), pointer :: eq_elements(:)
72  integer nodenum, idx
73 
74 #ifdef DEBUG
75  print *, "Converting XML subnodes to eq_structs"
76 #endif
77 
78  nodenum = SIZE( xmlsubnodes, 1)
79 
80 
81  allocate( eq_elements(nodenum) )
82  do idx = 1, nodenum
83  call convert2eq_struct( eq_struct, xmlsubnodes(idx) )
84 #ifdef DEBUG
85  print *, "localname of the current subnode: ", trim(xmlsubnodes(idx)%localname), " numfields: ", eq_struct%numfields
86 #endif
87 
88  call assocelement( eq_elements(idx), "subnode", eq_struct )
89 
90  end do
91 
92  allocate(subnodes)
93  subnodes%fields = c_loc(eq_elements(1))
94  subnodes%numfields = nodenum
95 
96 #ifdef DEBUG
97  print *, "Converting XML subnodes to eq_structs ------- finished"
98 #endif
99 
100 
101  end subroutine convertsubnodes2eq_struct
102 
103 
104 
105 !-------------------------------------------------------------------------------------------------
106 ! DESCRIPTION:
112  subroutine convert2eq_struct( eq_struct, node )
114  TYPE(eqstruct), pointer :: eq_struct
115  TYPE(xmlnode) :: node
116  TYPE(eqelement), pointer :: eq_elements(:)
117  TYPE(eqstruct), pointer :: subnodes => null()
118  character(len=:), pointer :: value
119  integer elementnum, idx
120 
121 #ifdef DEBUG
122  print *, "Converting XML node to eq_struct"
123 #endif
124 
125  ! converting subnodes/value
126  if ( hassubnodes(node) ) then
127  call convertsubnodes2eq_struct( subnodes, node%subnodes )
128  end if
129 
130 
131  ! first eq_element stores the localname
132  elementnum = 1
133 
134  if (ASSOCIATED(node%attrs)) then
135  elementnum = elementnum + SIZE( node%attrs, 1 )
136  end if
137 
138  if ((ASSOCIATED(node%subnodes)).or.(ASSOCIATED(node%value))) then
139  elementnum = elementnum + 1
140  end if
141 
142 
143  if (elementnum.eq.0 ) then
144  return
145  end if
146 
147  allocate( eq_elements(elementnum) )
148 
149 
150  ! converting the localname
151  allocate( character(len=LEN(node%localname)) :: value )
152  value = node%localname
153  call assocelement( eq_elements(1), "localname", value )
154  deallocate(value)
155 
156 
157  ! converting atrributes
158  if (ASSOCIATED(node%attrs)) then
159  do idx = 1, SIZE( node%attrs, 1 )
160  allocate( character(len=LEN(node%attrs(idx)%value)) :: value )
161  value = node%attrs(idx)%value
162  call assocelement( eq_elements(idx+1), node%attrs(idx)%name, value )
163  deallocate(value)
164  end do
165  end if
166 
167 
168  ! converting subnodes/value
169  if ( hassubnodes(node) ) then
170  call assocelement( eq_elements(elementnum), "subnodes", subnodes )
171 
172  else if (ASSOCIATED(node%value)) then
173  allocate( character(len=LEN(node%value)) :: value )
174  value = node%value
175  call assocelement( eq_elements(elementnum), "value", value )
176  deallocate(value)
177  end if
178 
179 #ifdef DEBUG
180  print *, "allocate ", trim(node%localname)
181 #endif
182  allocate( eq_struct )
183  eq_struct%fields = c_loc(eq_elements(1))
184  eq_struct%numfields = elementnum
185 
186 #ifdef DEBUG
187  print *, "Converting XML node to eq_struct ------ finished"
188 #endif
189 
190  end subroutine convert2eq_struct
191 
192 
193 
194 
195 
196 
197 !-------------------------------------------------------------------------------------------------
198 ! DESCRIPTION:
204  subroutine get_eq_structure( eq_struct, idx )
206  TYPE(eqstruct) :: eq_struct
207  TYPE(eqstruct), pointer :: peq_struct
208  integer idx
209 
210  if ( idx.gt.numtargetnodes ) then
211  print *, "maximal value for idx is: ", numtargetnodes
212  return
213  end if
214 
215  call convert2eq_struct( peq_struct, targetnodes(idx) )
216  eq_struct = peq_struct
217 
218  end subroutine get_eq_structure
219 
220 
221 !-------------------------------------------------------------------------------------------------
222 ! DESCRIPTION:
229 !
230  subroutine read_xml( fname, fname_len, cproperty_names, numofProperties)
232 
233  integer*8 fname_len
234  character(len=fname_len), intent(in) :: fname
235  logical :: file_exist
236  integer numofProperties
237  TYPE(c_ptr) :: cproperty_names(numofProperties)
238  character(len=MAX_PROP_LENGTH, kind=C_CHAR), pointer :: property_name
239 
240  TYPE(eqstruct) :: XML_node_tmp
241 
242  integer idx
243 
244 
245 
246 
247 
248 ! double check for the existence of the file
249  inquire(file=fname, exist=file_exist)
250  if (.not.file_exist) then
251  print *, 'File does not exist'
252  stop
253  endif
254 
255 ! Open the XML file
256  call open_xml_file(xp, fname, iostat=iostat)
257  if (iostat /= 0) then
258  write(*,*) "Cannot open file."
259  stop
260  endif
261 
262 
263  allocate( property_names(numofproperties))
264  do idx = 1, numofproperties
265  call c_f_pointer( cproperty_names(idx), property_name )
266  property_names(idx) = property_name
267  end do
268 
269 #ifdef DEBUG
270  print *, "Property names to be retrived:"
271  do idx = 1, numofproperties
272  print *, trim(property_names(idx))
273  end do
274 #endif
275 
277  endElement_handler = endElement_handler, &
281 
282 ! Close the XML file
283  call close_xml_t(xp)
284 
285 ! deallocating the property names
286  deallocate( property_names )
287 
288 #ifdef DEBUG
289  print *, new_line('A'), new_line('A'), new_line('A')
290  print *, "The retrived nodes:"
291  do idx = 1, SIZE( targetnodes, 1)
293  print *, new_line('A'), new_line('A')
294  end do
295 #endif
296 
297 
298 
299  end subroutine read_xml
300 
301 
302 
303 !-------------------------------------------------------------------------------------------------
304 ! DESCRIPTION:
308  subroutine deallocatetargetnodes()
310  integer idx
311 
312  do idx = 1, SIZE( targetnodes, 1)
313  call deallocatenode(targetnodes(idx))
314  end do
315  deallocate( targetnodes )
316 
317  end subroutine deallocatetargetnodes
318 
319 
320 
321 
322 
323 !-------------------------------------------------------------------------------------------------
324 ! DESCRIPTION:
329  subroutine addtargetnode( node )
330  TYPE(xmlnode), pointer :: node
331  TYPE(xmlnode), pointer :: nodes_tmp(:)
332  integer nodenum, idx
333 
334  if (.not.ASSOCIATED(targetnodes)) then
335  allocate(targetnodes(1))
336  call copynode(currenttargetnode, targetnodes(1))
337  numtargetnodes = 1
338  return
339  end if
340 
341 
342  nodenum = SIZE( targetnodes, 1 )
343  allocate( nodes_tmp(nodenum) )
344 
345  do idx = 1, nodenum
346  call copynode(targetnodes(idx), nodes_tmp(idx) )
347  end do
348 
349  deallocate( targetnodes )
350  allocate( targetnodes( nodenum+1 ) )
351  do idx = 1, nodenum
352  call copynode( nodes_tmp(idx), targetnodes(idx) )
353  end do
354  deallocate( nodes_tmp )
355 
356  call copynode( node, targetnodes(nodenum+1) )
357 
359 
360  end subroutine addtargetnode
361 
362 !-------------------------------------------------------------------------------------------------
363 ! DESCRIPTION:
369  logical function checkname( chunk )
370  character(len=*), intent(in) :: chunk
371  integer idx
372 
373  do idx = 1, SIZE( property_names, 1)
374  if ( chunk == property_names(idx) ) then
375  checkname = .true.
376  return
377  end if
378  end do
379 
380  checkname = .false.
381  return
382 
383  end function checkname
384 
385 
386 !-------------------------------------------------------------------------------------------------
387 ! DESCRIPTION:
392  subroutine error_handler(msg)
393  character(len=*), intent(in) :: msg
394  print *, "Error encountered and caught"
395  print *, msg
396  end subroutine error_handler
397 
398 !-------------------------------------------------------------------------------------------------
399 ! DESCRIPTION:
404  subroutine fatalerror_handler(msg)
405  character(len=*), intent(in) :: msg
406  print *, "Fatal error encountered and caught"
407  print *, msg
408  end subroutine fatalerror_handler
409 
410 
411 !-------------------------------------------------------------------------------------------------
412 ! DESCRIPTION:
417  subroutine characters_handler(chunk)
418  character(len=*), intent(in) :: chunk
419 
420  character(len=len(chunk)+1), pointer :: value
421 
422 
423  if (.not.targetnodeactive) then
424  return
425  endif
426 
427 ! XML node containing subnodes should not contain any value
428  if (ASSOCIATED(currentnode%subnodes)) then
429  currentnode%value => null()
430  return
431  end if
432 
433  allocate( character(len=len(chunk)+1) :: currentNode%value )
434  currentnode%value = trim(chunk)
435 #ifdef DEBUG
436  print *, "assigning value to the currentNode: ", trim(currentnode%value)
437 #endif
438 
439 
440 
441 
442 
443  end subroutine characters_handler
444 
445 !-------------------------------------------------------------------------------------------------
446 ! DESCRIPTION:
453  subroutine endelement_handler(URI, localname, name)
454  character(len=*), intent(in) :: URI
455  character(len=*), intent(in) :: localname
456  character(len=*), intent(in) :: name
457 
458 
459  if ( targetnodeactive ) then
460  ! the target node is going out of scope
461  if ( subnodelevel.eq.currenttargetnode%subnodelevel ) then
462 #ifdef DEBUG
463 print *, "Deactivatig the current target node"
464 #endif
465  targetnodeactive = .false.
467  currenttargetnode => null()
468  currentnode => null()
469  end if
470 
471  else
473  return
474  end if
475 
476 
477 
478  if (ASSOCIATED(currentnode) ) then
479  if (ASSOCIATED(currentnode%parentnode)) then
480  call addsubnode( currentnode%parentnode, currentnode )
481  currentnode => currentnode%parentnode
482  end if
483  end if
484 
486 
487  end subroutine endelement_handler
488 
489 
490 !-------------------------------------------------------------------------------------------------
491 ! DESCRIPTION:
499  subroutine startelement_handler(URI, localname, name,attributes)
500  character(len=*), intent(in) :: URI
501  character(len=*), intent(in) :: localname
502  character(len=*), intent(in) :: name
503  type(dictionary_t), intent(in) :: attributes
504 
505 
506  type(xmlnode), pointer :: parentnode
507 
508  integer :: idx
509  character(len=MAX_PROP_LENGTH), pointer :: XML_attr_value(:)
510 
511  TYPE( attrib ), pointer :: attrs(:)
512  type(xmlnode), pointer :: subnode
513 
514 ! The number of XML attributes in a given node
515  integer :: XML_attributes_num
516 
518 
519  if ( .not.targetnodeactive ) then
520  call createtargetnode( uri, localname, name,attributes )
522  return
523  end if
524 
525 
526  ! create subnode in the current target node
527 #ifdef DEBUG
528 print *, "allocating subnode: ", localname
529 #endif
530 
531  allocate( subnode )
532  xml_attributes_num = getlength(attributes)
533 
534  subnode%subnodelevel = subnodelevel
535  subnode%localname = trim(localname)
536  subnode%subnodes=> null()
537  subnode%value=> null()
538  allocate( subnode%attrs(xml_attributes_num) )
539 
540  do idx = 1, getlength(attributes)
541  subnode%attrs(idx)%name = trim(getqname(attributes, idx))
542  subnode%attrs(idx)%value = trim(getvalue(attributes, idx))
543  enddo
544 
545 
546  subnode%parentnode => currentnode
547  currentnode => subnode
548 
549  end subroutine startelement_handler
550 
551 
552 
553 !-------------------------------------------------------------------------------------------------
554 ! DESCRIPTION:
562  subroutine createtargetnode(URI, localname, name,attributes)
563  character(len=*), intent(in) :: URI
564  character(len=*), intent(in) :: localname
565  character(len=*), intent(in) :: name
566  type(dictionary_t), intent(in) :: attributes
567 
568 ! The number of XML attributes in a given node
569  integer :: XML_attributes_num
570 
571  integer :: idx
572  character(len=MAX_PROP_LENGTH), pointer :: XML_attr_value(:)
573 
574  TYPE( attrib ), pointer :: attrs(:)
575 
576  ! retriving the attributes of a desired property
577  if ( (localname.EQ."property").OR. &
578  (localname.EQ."propertyList") ) then
579  do idx = 1, getlength(attributes)
580  if ( (getqname(attributes, idx)=="dictRef").OR. &
581  (getqname(attributes, idx)=="title")) then
582  if (checkname( getvalue(attributes, idx) )) then
583  xml_attributes_num = getlength(attributes)
584  targetnodeactive = .true.
585  endif
586  endif
587  enddo
588 
589  if ( .not.targetnodeactive ) then
590  return
591  end if
592 #ifdef DEBUG
593 print *, "Allocating target node"
594 #endif
595  allocate(currenttargetnode)
596  currenttargetnode%subnodelevel = subnodelevel
597  currenttargetnode%localname = trim(localname)
598  currenttargetnode%subnodes=> null()
599  currenttargetnode%parentnode=> null()
600  currenttargetnode%value=> null()
601  allocate( currenttargetnode%attrs(xml_attributes_num) )
602 
603  do idx = 1, getlength(attributes)
604  currenttargetnode%attrs(idx)%name = trim(getqname(attributes, idx))
605  currenttargetnode%attrs(idx)%value = trim(getvalue(attributes, idx))
606  enddo
607 
608  return
609  end if
610 
611 
612  end subroutine createtargetnode
613 
614 
615 
616 
617 end module
618 
619 
subroutine convert2eq_struct(eq_struct, node)
subroutine createtargetnode(URI, localname, name, attributes)
subroutine fatalerror_handler(msg)
subroutine characters_handler(chunk)
subroutine error_handler(msg)
subroutine startelement_handler(URI, localname, name, attributes)
logical function checkname(chunk)
logical, private targetnodeactive
subroutine convertsubnodes2eq_struct(subnodes, XMLsubnodes)
subroutine get_eq_structure(eq_struct, idx)
type(xmlnode), pointer currentnode
logical function hassubnodes(cXMLnode)
Definition: XML.f90:71
integer numtargetnodes
subroutine deallocatetargetnodes()
type(xmlnode), dimension(:), pointer targetnodes
subroutine printnodewithsubnodes(node)
Definition: XML.f90:155
subroutine endelement_handler(URI, localname, name)
type(xmlnode), pointer currenttargetnode
type(xml_t), private xp
character(len=max_prop_length, kind=c_char), dimension(:), pointer property_names
integer, private subnodelevel
subroutine addtargetnode(node)
subroutine read_xml(fname, fname_len, cproperty_names, numofProperties)