2016-08-22 2 views
2

Я пытаюсь помочь клиенту, который был недоволен системой EMR (Electronic Medical Records) и хотел переключиться, но компания заявила, что не может извлечь демографические данные пациента из базы данных (мы спросили, могут ли они получить нам имя, адрес, доб в каком-то файле csv, очень простые вещи), но они утверждают, что они не могут этого сделать. (сумасшедший, учитывая, что они используют базу данных sql). В любом случае - то, как они передавали пациентов, находилось в файлах xml, и их было около 40 000+. Но они содержат намного больше, чем демографические данные. После ряда исследований и проделанного обширного программирования на Perl 15 лет назад (я признаю, что с годами он ржавый). Я думал, что это должна быть хорошая задача, чтобы сделать это в Perl, - и я наткнулся на модуль XML :: Twig, который похоже, в состоянии сделать трюк. К сожалению, XML-код, который представляет интерес выглядит следующим образом:XML :: Twig синтаксический анализ тегов с тем же именем

< == надрез ==>

<patient extension="Patient ID Number"> // <--Patient ID is 5 digit number) 
    <name> 
    <family>Patient Family name</family> 
    <given>Patient First/Given name</given> 
    <given>Patient Middle Initial</given> 
    </name> 
    <birthTime value=YEARMMDD"/> 

несколько полей для адреса etc.are следующие в файле XML.

< == надрез ==>

Вот что я закодированы:

my $twig=XML::Twig->new(twig_handlers => { 
    'patient/name/family'  => \&get_family_name, 
    'patient/name/given'  => \&get_given_name 
}); 
$twig->parsefile('test.xml'); 

my @fields; 

sub get_family_name {my($twig,$data)[email protected]_;$fields[0]=$data->text;$twig->purge;} 
sub get_given_name {my($twig,$data)[email protected]_;$fields[1]=$data->text;$twig->purge;} 

У меня никаких проблем не читая всю информацию, которые имеют уникальные метки (семья, город, почтовый индекс, и т.д. .), но XML: Twig возвращает только средний начальный элемент для тега. Как я могу обратиться к первому вступлению «заданного» и присвоить ему $ fields [1] и второе вхождение «заданных» в $ fields [2], например, или вырезать средний начальный.

Также как извлечь «Идентификатор пациента» или значение «BirthTime» с помощью XML :: Twig - я не мог найти ссылку на это. Я пробовал использовать $ data-> findvalue ('BirthTime'), но это оказалось пустым.

Я смотрел: Perl, XML::Twig, how to reading field with the same tag, который был очень полезен, но поскольку повторяющиеся теги находятся в одном и том же пути, они разные, и я не могу найти ответ. XML: Twig возвращает только последнее значение, найденное при поиске совпадения при разборе файла? Есть ли способ извлечь все вхождения значения?

Благодарим вас за помощь!

ответ

2

Очень легко предположить из документации, что вы предположили для использования обратных вызовов для всего. Но так же справедливо разбирать весь документ и допрашивать его целиком, особенно если размер данных мал.

Непонятно, у вашего вопроса, есть ли у каждого пациента отдельный XML-файл, и вы не показываете то, что окружает patient элементы, но я предлагаю вам использовать компромиссный подход и написать обработчик для только patient элементов, который извлекает всю информацию требуется

Я решил построить хэш информации %patient из каждого patient и надавите на массив @patients, содержащий все данные в файле. Если у вас есть только один пациент на файл, тогда это нужно будет изменить.

Я решил проблему с элементами name/given, извлекая все из них и объединив их в одну строку с промежуточными пространствами.Я надеюсь, что это подходит

Это совершенно непроверено, поскольку в настоящее время у меня есть только таблетка, так что будьте осторожны. У него есть шанс на компиляцию, но я был бы удивлен, если бы у него не было ошибок.

use strict; 
use warnings 'all'; 

use XML::Twig; 

my @patients; 

my $twig = XML::Twig->new(
    twig_handlers => { patient => \&get_patient } 
); 
$twig->parsefile('test.xml'); 

sub get_patient { 
    my ($twig, $pat) = @_; 

    my %patient; 

    $patient{id} = $pat>att('extension'); 

    my $name   = $pat->first_child('name');yy 
    $patient{family} = $name->first_child_trimmed_text('family'); 
    $patient{given} = join ' ', $name->children_trimmed_text('given'); 

    $patient{dob} = $pat->first_child('birthTime')->att('value'); 

    push @patients, \%patient; 
} 
+0

Привет, спасибо за быстрый ответ, я попробую сегодня. Но на ваш вопрос - у каждого пациента есть свой собственный XML-файл, и у нас есть около 40 000 + из них, которые мне нужно проанализировать. И да, я забыл закрыть пациента в последней строке - немного разобраться в форматировании в поле вопроса - и потом забыл добавить это в конце (так как copy & paste не работает в текстовом поле для кода кажется). – yoeddy

+0

Привет, Бородин, большое вам спасибо за вашу помощь. То, что вы опубликовали, помогло мне лучше понять модуль Twig, и я могу проанализировать нужные мне данные. Нет. Я могу работать над очисткой данных и запускать их через эти файлы. Спасибо! – yoeddy

+0

И, наконец, еще один вопрос - я люблю толкать хэш в глобальный массив - очень аккуратно и чисто. Мой вопрос: если мне придется разбирать 40 000 файлов, это будет проблема? В этом массиве есть 40'000 + хэшей? Может ли perl обрабатывать такие большие массивы - или было бы лучше написать результаты каждого файла, анализируемого прямо в файл csv? Наверное, я спрашиваю, являются ли небольшие файловые операции более ресурсоемкими, чем заполнение массива 40-тысячными хэшами и их запись в конце в файл csv? Спасибо! :) – yoeddy