Я предпочитаю XPath для таких вещей:
In [1]: from lxml.etree import parse
In [2]: tree = parse('/tmp/database.xml')
In [3]: for post in tree.xpath('/Database/BlogPost'):
...: print 'Author:', post.xpath('Author')[0].text
...: print 'Content:', post.xpath('Content')[0].text
...:
Author: Last Name, Name
Content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas dictum dictum vehicula.
Author: Last Name, Name
Content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas dictum dictum vehicula.
Author: Last Name, Name
Content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas dictum dictum vehicula.
Я не уверен, что он отличается от обработки больших файлов. Замечания об этом будут оценены.
Выполняйте свой путь,
for event, element in etree.iterparse(path_to_file, tag="BlogPost"):
for info in element.iter():
if info.tag in ('Author', 'Content'):
print info.tag, ':', info.text
Да, ваш формат не подходит для данных, которые вы показываете. Лучше должно быть так read(99,'(6(E11.4,X))') myData(i,:)
.
Тем не менее, я не уверен, что вам действительно нужно использовать формат при чтении вообще.
Ниже приведен пример, близкий к тому, что вы пытаетесь сделать, и он работает ботом с форматом и без него.
program readdata
implicit none
real, allocatable :: myData(:,:)
real :: myLine
integer :: i, j, myRow, myColumn
character(len=30) :: myFileName
character(len=30) :: myFormat
myFileName='data.dat'
open(99, file=myFileName)
write(*,*)'open data file'
read(99, *) myRow
read(99, *) myColumn
allocate(myData(myRow,myColumn))
do i=1,myRow
read(99,*) myData(i,:)
!read(99,'(6(E11.4,X))') myData(i,:)
print*, myData(i,:)
enddo
close(99)
end program readdata
Чтобы проверить, я предположил, что у вас всегда есть строки и столбцы в файле, так как мои тестовые данные следуют.
2
6
2.9900E-35 2.8000E-35 2.6300E-35 2.4600E-35 2.3100E-35 2.1600E-35
2.9900E-35 2.8000E-35 2.6300E-35 2.4600E-35 2.3100E-35 2.1600E-35
Если вам действительно интересно прочитать ваши файлы в формате, и если количество столбцов не является постоянным, вам может понадобиться формат в зависимости от переменной, см. связанные обсуждения здесь .
Хотя нет прямой команды для подсчета количества элементов в строке, мы можем подсчитать количество периодов или (E | e | D | d) с помощью команды scan . Например,
program main
implicit none
character(100) str
integer n
read( *, "(a)" ) str
call countreal( str, n )
print *, "number of items = ", n
contains
subroutine countreal( str, num )
implicit none
character(*), intent(in) :: str
integer, intent(out) :: num
integer pos, offset
num = 0
pos = 0
do
offset = scan( str( pos + 1 : ), "." ) !! (1) search for periods
!! offset = scan( str( pos + 1 : ), "EeDd" ) !! (2) search for (E|e|D|d)
if ( offset > 0 ) then
pos = pos + offset
num = num + 1
print *, "pos=", pos, "num=", num !! just for check
else
return
endif
enddo
endsubroutine
end
Обратите внимание, что шаблон (1) работает только тогда, когда все элементы имеют периоды, а шаблон (2) работает только тогда, когда все элементы имеют показатели:
# When compiled with (1)
$ echo "2.9900 2.8000E-35 2.6300D-35 2.46 2.31" | ./a.out
pos= 2 num= 1
pos= 10 num= 2
pos= 22 num= 3
pos= 34 num= 4
pos= 40 num= 5
number of items = 5
# When compiled with (2)
$ echo "2.9900E-35 2.8000D-35 2.6300e-35 2.4600d-35" | ./a.out
pos= 7 num= 1
pos= 19 num= 2
pos= 31 num= 3
pos= 43 num= 4
number of items = 4
Для более общих целей может быть удобнее написать пользовательскую функцию split (), которая разделяет элементы с пробелами (или использует внешнюю библиотеку, которая поддерживает функцию split).