Извлечение данных между двумя тегами в файле HTML - PullRequest
2 голосов
/ 05 июля 2011

Я сохранил огромный файл HTML, сохраненный в моей системе, который содержит данные из каталога продуктов.Данные структурированы таким образом, что для каждой записи о продукте имя находится между двумя тегами (имя) и (/ имя).

Каждый продукт имеет до 3 атрибутов: имя, идентификатор продукта и цвет, но не все продуктыбудет иметь все эти атрибуты.

Как бы я извлек эти данные для каждого продукта, не смешивая атрибуты продукта?Файл также 50 мегабайт!

Пример кода ....

<name>'hat'</name>
blah blah blah
<prodId>'1829493'</prodId>
blah blah blah
<color>'cyan'</color>

blah blah 
blah blah blah
blah blah blah

<name>'shirt'</name>
blah blah blahblah blah blah
<prodId>'193'</prodId>

<name>'dress'</name>
blah blah blah
blah blah blah
<prodId>'18'</prodId>
<color>'dark purple'</color>

Ответы [ 2 ]

5 голосов
/ 05 июля 2011

Файл размером 50 МБ не такой большой, что вы не можете просто загрузить его содержимое непосредственно в MATLAB в виде строки, что вы можете сделать с помощью функции FILEREAD :

strContents = fileread('yourfile.html');

Предполагая, что формат файла у вас есть выше, вы можете затем проанализировать содержимое с помощью функции REGEXP (используя захват именованного токена ):

expr = '<(?<tag>name|prodId|color)>''([^<>]+)''</\k<tag>>';
tokens = regexp(strContents,expr,'tokens');
tokens = vertcat(tokens{:});

И содержимое token, использующее содержимое файла примера:

tokens = 

    'name'      'hat'        
    'prodId'    '1829493'    
    'color'     'cyan'       
    'name'      'shirt'      
    'prodId'    '193'        
    'name'      'dress'      
    'prodId'    '18'         
    'color'     'dark purple'

Затем вы можете проанализировать полученный массив ячеек N-на-2 и поместить содержимое в структурный массив с полями 'name', 'prodId' и 'color'. Сложность в том, что не каждая запись будет иметь все три поля. Предполагая, что за каждым 'name' будут следовать либо 'prodId', 'color' или оба (в порядке 'prodId' затем 'color'), затем следующее код должен работать для вас:

s = struct('name',[],'prodId',[],'color',[]);  %# Initialize structure
nTokens = size(tokens,1);                      %# Get number of tokens
nameIndex = find(strcmp(tokens(:,1),'name'));  %# Find indices of 'name'
[s(1:numel(nameIndex)).name] = deal(tokens{nameIndex,2});  %# Fill 'name' field

%# Find and fill 'prodId' that follows a 'name':
index = strcmp(tokens(min(nameIndex+1,nTokens),1),'prodId');
[s(index).prodId] = deal(tokens{nameIndex(index)+1,2});

%# Find and fill 'color' that follows a 'name':
index = strcmp(tokens(min(nameIndex+1,nTokens),1),'color');
[s(index).color] = deal(tokens{nameIndex(index)+1,2});

%# Find and fill 'color' that follows a 'prodId':
index = strcmp(tokens(min(nameIndex+2,nTokens),1),'color');
[s(index).color] = deal(tokens{min(nameIndex(index)+2,nTokens),2});

И содержимое s с использованием содержимого вашего файла примера будет:

>> s(1)

      name: 'hat'
    prodId: '1829493'
     color: 'cyan'

>> s(2)

      name: 'shirt'
    prodId: '193'
     color: []

>> s(3)

      name: 'dress'
    prodId: '18'
     color: 'dark purple'
0 голосов
/ 05 июля 2011

Существует два способа решения такого рода проблем: манипулирование строками с помощью регулярных выражений (как предложено gnovice) или синтаксический анализ файла (или их сочетание).Разбор часто лучше, если ваш файл очень хорошо структурирован;регулярные выражения выигрывают для грязных файлов.

Вот решение для анализа.

Начните с загрузки xmliotools и вызова xml_read для вашего файла.Ваш пример не полностью воспроизводим, поэтому здесь представлены две разные версии данных.

Сохраните это в test1.xml:

<?xml version="1.0" encoding="utf-8"?>
<root>
<name>'hat'</name>
<prodId>'1829493'</prodId>
<color>'cyan'</color>
<name>'dress'</name>
<prodId>'18'</prodId>
<color>'dark purple'</color>
</root>

Сохраните это в test2.xml.

<?xml version="1.0" encoding="utf-8"?>
<root>
<item>
<name>'hat'</name>
<prodId>'1829493'</prodId>
<color>'cyan'</color>
</item>
<item>
<name>'dress'</name>
<prodId>'18'</prodId>
<color>'dark purple'</color>
</item>
</root>

Теперь сравните

x1 = xml_read('test1.xml')
x2 = xml_read('test2.xml')
...