Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

XML in Fortran

NBG6
Beginner
1,597 Views
Hello everybody!

Does anybody developed an interface F90 <-> XML-Files (read/write node values, read/write attributes)?

If not - would anybody do this for my company USING FORTRAN (of course we'll pay for this)?

Thanks a lot
0 Kudos
10 Replies
Arjen_Markus
Honored Contributor I
1,597 Views
There are several Fortran libraries around that will allow you to manipulate XML files from Fortran.

You can have a look at my xml-fortran project: http:://xml-fortran.sf.net

Regards,

Arjen
0 Kudos
NBG6
Beginner
1,597 Views
Thank you Arjen,

I will try this.

Some more questions :
1. Is it possible to expand the limit to more than 1000 chars per line?
2. Can I add or edit one single attribute within an XML-file using XML_put subroutine?
3. Can I put a new node inbetween 2 existing nodes?

If you do not have time to answer I will go through the routines to find out it myself (it is easier to ask directly ;-)

Thanks
0 Kudos
Arjen_Markus
Honored Contributor I
1,597 Views
Wrt your questions:

1. Yes, change the value of the parameter XML_BUFFER_LENGTH and recompile
2. You would need to rewrite the entire file - that is simply a problem of files in general
(has nothing to do with this library)
3. Yes, but it depends on the way you want to work with it all

There are roughly two ways of dealing with XML files:
- Read the whole file into a structure in memory and manipulate that
- Read/write it as you go along

If you need to manipulate the structure, you are better off with the first method.
Otherwise the second might be worthwhile - for instance if you have very large
files.

Regards,

Arjen
0 Kudos
NBG6
Beginner
1,597 Views
Hi Arjen,

Thanks and some remarks:

Doesn't it take a long time in case of big XML-files (performance of the program)? I would like to handle (read values, manipulate structure, add nodes etc) very long files and thougt that there would be a possibility to not read the complete file into a virtual file or array or whatever. But I think I have to do so. I am also not able to go along the file because I have to read nodes/attributes spread over the complete file.

In VB.NET it is possible to modify the file using XML classes without reading the complete file. How do they do this???!!!

I will try your project now- thanks for the help!

0 Kudos
Arjen_Markus
Honored Contributor I
1,597 Views
My project allows several ways of working.
One is:
- Define the structure of the XML files you want
- Generate the source code to read and write such files
- With the reading routine you read the entire file and then you
can manipulate the contents
- With the writing routine you write it back

Another way is to load the file into a tree of elements.
This has no fixed structure so you are free to add attributes
and what not, but it is a bit more work.

In my experience reading is pretty fast and the data structures
produced are pretty slim. Only if you get into the range of
hundreds of MBs, I would get to worry about performance
or memory - but then there are better ways to store large
amounts of data than XML files.

Regards,

Arjen
0 Kudos
thomas_boehme
New Contributor II
1,597 Views
We are currently reading and writing large XML files with FORTRAN with great success.

Initially, we checked out FoX, but it showed very bad performance on larger files and wasn't reliable enough for us.

What we did in the end was use Microsoft's msxml6.dll viaits COM interface.It worksreally well for us and gives you access to all functionality in Microsoft's XML library. It is quite well suited for manipulating large XML files as it provides a complete DOM model.

There are some issues you have to work through to get started, though. I did explain some of the detailsin the following thread:
http://software.intel.com/en-us/forums/showthread.php?t=70220&o=a&s=lr

Best wishes,
Thomas


0 Kudos
NBG6
Beginner
1,597 Views
Hi Thomas,

I worked through to your description and it worked fine - going step by step to your receipt and it worked immediately - Thanks for the help.

I still have some trouble using other functions than XMLGetString. Some of the data are not char but double precision or integer values and I already tried IXMLDOMCharacterData_Getdata and IXMLDOMNode_GetnodeValue. Till now was not successful because of correct using of variables of type VARIANT.

When it works I will post it (when I find out how it works).

Thanks

0 Kudos
thomas_boehme
New Contributor II
1,597 Views

Hi NBG6,

Great to hear that you have success with the instructions.

I always use XMLGetString to get most of the data and do any needed conversions myself.

I do use some functions that require variants. Which functions do you experience problems with?

E.g. to generate a integer variant, you can use the following code:

[fortran]TYPE (variant) FUNCTION  NewIntegerVariant(IVal)
  IMPLICIT NONE
  ! Subroutine arguments
  INTEGER(ZIP),INTENT(IN)   ::  IVal
  CALL VariantInit( NewIntegerVariant )
  NewIntegerVariant%VT = VT_I4
  NewIntegerVariant%VU%LONG_VAL = IVal
end function

[/fortran]
You should remeber that you have to delete the variant using result = VariantClear( Var ) when you no longer need it
VariantInit and VariantClearare part of IFCOM.

Also, you should be very careful with any COM objects returned by the msxml6.dll. Remember to release all of them using Status = COMReleaseObject($COM) when no longer needed.

best regards,
Thomas





					
				
			
			
				
			
			
			
			
			
			
			
		
0 Kudos
NBG6
Beginner
1,597 Views
Hi Thomas,

Thanks a lot for the hints.

Now I (hopefully) got it.
It was not a problem of Variant datatype but in creating the string for the node name.

For an XML structure like this:

-

-

-

-

-

DE6-170B-23


I have to put to the XMLGetString function the following path:

xPath='Turbine/Stage_Groups/Stage_Group_Data[@Stage_Group_ID="2"]/Stage_Data[@Stage_ID="2"]/Blade_Data[@St_Bl="Rot_Bl"]/Rotor_Airfoil_Name '

!calling the function
CALL XMLGetString($xmlDocument, xPath, StrRes)

!yields to the result"DE6-170B-23" and this is exactly what I want!

Great!

Now I will try to read some attributes and write some node values.

I will keep you informed.

Thanks again.

0 Kudos
NBG6
Beginner
1,597 Views
Hi everybody!

*******************************************************************
This message is obsolete -->
My colleaguefound the error - I just forgot the $ in the function call!
*******************************************************************

I get an access violation error while use of XML save function:

!------------------------------------------------------------------------------------- SaveXmlFile

SUBROUTINE SaveXmlFile( $XMLDocument, filename )

! 30.09.2010 bernommen von Thomas Boehme aus Intel-Forum

!-----------------------------------------------------------------------

IMPLICIT NONE

INTEGER(INT_PTR_KIND()) :: $XMLDocument

CHARACTER *(*) :: filename

INTEGER(INT_PTR_KIND()) :: dummy

type (VARIANT) :: variantString

!Umwandlung des char filename in einen Variant-Datentyp

variantString = NewStringVariant( filename )

dummy = $IXMLDOMDocument_save($XMLDocument, variantString )

!Freigeben des Variant-Datentyp

CALL DeleteStringVariant( variantString )

END SUBROUTINE SaveXmlFile
!----------------------------------------------------------------------------------

The error occurs in line:
dummy = IXMLDOMDocument_save($XMLDocument, variantString )

The pointer of $XMLDoument is available, the pointer to variantString is avaiable as well.

In the interface from MSXML6 :
!----------------------------------------------------------------------------------------
INTERFACE

!save the document to a specified destination

INTEGER(4) FUNCTION IXMLDOMDocument_save($OBJECT, destination)

USE IFWINTY

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer

!DEC$ ATTRIBUTES VALUE :: $OBJECT

TYPE (VARIANT), INTENT(IN) :: destination

!DEC$ ATTRIBUTES VALUE :: destination

!DEC$ ATTRIBUTES STDCALL :: IXMLDOMDocument_save

END FUNCTION IXMLDOMDocument_save

END INTERFACE

POINTER(IXMLDOMDocument_save_PTR, IXMLDOMDocument_save) ! routine pointer
!-------------------------------------------------------------------------------------------------

I tried both
!DEC$ ATTRIBUTES VALUE:: destination
and
!DEC$ ATTRIBUTES REFERENCE :: destination

but it did not work.

Does anybody got an idea?

0 Kudos
Reply