在HTML文件中提取两个标签之间的数据

时间:2011-07-05 11:56:06

标签: html xml matlab extract large-files

我的系统上保存了一个HUUUGE HTML文件,其中包含产品目录中的数据。数据的结构使得每个产品记录的名称都在两个标签(名称)和(/名称)之间。

每个产品最多有3个属性:name,productID和color,但并非所有产品都具有所有这些属性。

如何在不混淆产品属性的情况下为每种产品提取此数据?该文件也是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 个答案:

答案 0 :(得分:5)

大小为50 MB的文件不是那么大,你不能只将它的内容作为字符串直接加载到MATLAB中,你可以用函数FILEREAD来完成:

strContents = fileread('yourfile.html');

假设您拥有上面的文件格式,您可以使用函数REGEXP解析内容(使用named token capture):

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-by-2单元格数组,并将内容放在structure array中,其中包含字段'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'

答案 1 :(得分:0)

有两种方法可以解决这类问题:使用正则表达式进行字符串操作(如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')