├── README.md ├── VOCxml_to_matlab_main.m ├── matlab_to_VOCxml.m ├── matlab_to_pixel.m ├── matlab_to_txt.m ├── pixel_to_matlab.m ├── pixel_to_matlab_old.m ├── stopSignImages ├── image001.jpg ├── image001.png ├── image001.txt ├── image001.xml ├── image002.jpg ├── image002.png ├── image002.txt ├── image002.xml ├── image003.jpg ├── image003.png ├── image003.txt ├── image003.xml ├── image004.jpg ├── image004.png ├── image004.txt ├── image004.xml ├── image005.jpg ├── image005.png ├── image005.txt ├── image005.xml ├── image006.jpg ├── image006.png ├── image006.txt ├── image006.xml ├── image007.jpg ├── image007.png ├── image007.txt ├── image007.xml ├── image008.jpg ├── image008.png ├── image008.txt ├── image008.xml ├── image009.jpg ├── image009.png ├── image009.txt ├── image009.xml ├── image010.jpg ├── image010.png ├── image010.txt ├── image010.xml ├── image011.jpg ├── image011.png ├── image011.txt ├── image011.xml ├── image012.jpg ├── image012.png ├── image012.txt ├── image012.xml ├── image013.jpg ├── image013.png ├── image013.txt ├── image013.xml ├── image014.jpg ├── image014.png ├── image014.txt ├── image014.xml ├── image015.jpg ├── image015.png ├── image015.txt ├── image015.xml ├── image016.jpg ├── image016.png ├── image016.txt ├── image016.xml ├── image017.jpg ├── image017.png ├── image017.txt ├── image017.xml ├── image018.jpg ├── image018.png ├── image018.txt ├── image018.xml ├── image019.jpg ├── image019.png ├── image019.txt ├── image019.xml ├── image020.jpg ├── image020.png ├── image020.txt ├── image020.xml ├── image021.jpg ├── image021.png ├── image021.txt ├── image021.xml ├── image022.jpg ├── image022.png ├── image022.txt ├── image022.xml ├── image023.jpg ├── image023.png ├── image023.txt ├── image023.xml ├── image024.jpg ├── image024.png ├── image024.txt ├── image024.xml ├── image025.jpg ├── image025.png ├── image025.txt ├── image025.xml ├── image026.jpg ├── image026.png ├── image026.txt ├── image026.xml ├── image027.jpg ├── image027.png ├── image027.txt ├── image027.xml ├── image028.jpg ├── image028.png ├── image028.txt ├── image028.xml ├── image029.jpg ├── image029.png ├── image029.txt ├── image029.xml ├── image030.jpg ├── image030.png ├── image030.txt ├── image030.xml ├── image031.jpg ├── image031.png ├── image031.txt ├── image031.xml ├── image032.jpg ├── image032.png ├── image032.txt ├── image032.xml ├── image033.jpg ├── image033.png ├── image033.txt ├── image033.xml ├── image034.jpg ├── image034.png ├── image034.txt ├── image034.xml ├── image035.jpg ├── image035.png ├── image035.txt ├── image035.xml ├── image036.jpg ├── image036.png ├── image036.txt ├── image036.xml ├── image037.jpg ├── image037.png ├── image037.txt ├── image037.xml ├── image038.jpg ├── image038.png ├── image038.txt ├── image038.xml ├── image039.jpg ├── image039.png ├── image039.txt ├── image039.xml ├── image040.jpg ├── image040.png ├── image040.txt ├── image040.xml ├── image041.jpg ├── image041.png ├── image041.txt └── image041.xml ├── table_to_gTruth.m ├── txt_to_matlab.m └── xml_io_tools ├── code ├── base64decode.m ├── base64encode.m ├── gen_object_display.m ├── html │ ├── test.html │ ├── xml_tutorial_script.html │ ├── xml_tutorial_script.png │ └── xml_tutorial_script_01.png ├── license.txt ├── test.xml ├── test_file.xml ├── xml_read.m ├── xml_tutorial_script.m ├── xml_write.m └── xmlwrite_xerces.m └── readme.txt /README.md: -------------------------------------------------------------------------------- 1 | # Image Labeler app 2 | 本程序旨在标注图像文件简单交互式格式互转,支持拖曳矩形框,像素语义级别两种类型标注。
3 | 共提供6个接口(函数),具体转换关系图如下:
4 | VOCxml<------->Matlab groundTruth,rectangle
5 | txt<------->Matlab groundTruth,rectangle
6 | png(pixel)<------->Matlab groundTruth,pixel
7 | 其中Matlab table格式可以在MATLAB2017b(及以后新版本)中imageLabeler/trainingImageLabeler APP中修改/查看等等操作,方便自由~

8 | 9 | 注意:xml_io_tools_2010_11_05.zip为安装文件,解压加入到工作路径即可使用(文件已包含)。 10 | 下载链接:http://cn.mathworks.com/matlabcentral/fileexchange/12907-xml-io-tools 11 | 12 | ## 6个接口(额外1个配最新版本转gTruth) 13 | VOCxml_to_matlab_main.m为批量VOC-xml转MATLAB table格式文件;
14 | matlab_to_VOCxml.m为MATLAB table转VOC-xml格式文件;
15 | txt_to_matlab.m为txt文本转MATLAB table格式文件;
16 | table_to_gTruth.m为table格式转换groundTruth格式;
17 | matlab_to_txt.m为MATLAB table转txt文本格式。
18 | pixel_to_matlab.m为png像素标注转MATLAB groundTruth格式文件;
19 | matlab_to_pixel.m为MATLAB groundTruth转png像素级别标注格式。
20 | 21 | ## txt文本标记格式 22 | 比如文本内容打开如下,分别表示类别,x,y,width,height,四个缺省值0,txt和xml中像素是以0开始的索引:
23 | 3
24 | car 401 381 305 201 0 0 0 0
25 | car 149 377 234 143 0 0 0 0
26 | stop 858 318 39 43 0 0 0 0
27 | 28 | ## Tips 29 | MATLAB groundTruth格式文件由imageLabeler APP导出/制作查看的格式,适合2017b及以后版本。 30 | 原图像与标注文件要位于同一目录并且一一对应,文件名相同,后缀不同,参考“stopSignImages”标注样式。 31 | 32 | -------------------------------------------------------------------------------- /VOCxml_to_matlab_main.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/VOCxml_to_matlab_main.m -------------------------------------------------------------------------------- /matlab_to_VOCxml.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/matlab_to_VOCxml.m -------------------------------------------------------------------------------- /matlab_to_pixel.m: -------------------------------------------------------------------------------- 1 | function matlab_to_pixel(groundTruthData) 2 | % 功能:把matlab imageLabeler APP中的groundTruth变量导出到语义标记png中, 3 | % 每个图像对应一个png标注图像。 4 | %输入: 5 | % groundTruthData,groundTruth类型或table类型标注文件 6 | %输出:无 7 | % 8 | %Example ; 9 | % matlab_to_pixel(groundTruthData) 10 | % 11 | 12 | if ~isa(groundTruthData,'groundTruth') 13 | error('请在matlab imageLabeler APP中导出标注变量数据!'); 14 | end 15 | 16 | labelDatas = groundTruthData.LabelData.PixelLabelData; 17 | oriDatas = groundTruthData.DataSource.Source; 18 | if ~iscell(oriDatas) 19 | oriDatas = oriDatas.Files; 20 | end 21 | 22 | parfor i = 1:length(labelDatas) 23 | src = labelDatas{i}; 24 | dstname = oriDatas{i}; 25 | dst = [dstname(1:end-4),'.png']; 26 | movefile(src,dst); 27 | end 28 | [folder,~,~] = fileparts(labelDatas{1}); 29 | if exist(folder,'dir') 30 | rmdir(folder); 31 | end 32 | -------------------------------------------------------------------------------- /matlab_to_txt.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/matlab_to_txt.m -------------------------------------------------------------------------------- /pixel_to_matlab.m: -------------------------------------------------------------------------------- 1 | function gTruth = pixel_to_matlab(pixelLabelDir,labelnames) 2 | % 功能:多类别像素级语义分割标记导入,根据原图(jpg格式)和标记图(同名同大小的png格式, 3 | % uint8类型,从1开始的类别标记矩阵,0为背景类),生成groundTruth类型对象,最后可导入到imageLabeler APP中, 4 | % 原图和标记图要位于同一目录下 5 | % 6 | % 输入: 7 | % pixelLabelDir: 原图和标记图根目录,一副jpg原图对应一副png标记图 8 | % labelnames: 标记类型标签,cell array或者string数组类型 9 | % 输出: 10 | % gTruth: groundTruth类型标注信息文件,可直接导入到matlab imageLabeler APP中查看 11 | % 12 | % Example: 13 | % gTruth = pixel_to_matlab() 14 | % 15 | arguments % arguments, Introduced in R2019b 16 | pixelLabelDir (1,:) char = '' 17 | labelnames (1,:) string = "undefined" 18 | end 19 | 20 | if isempty(pixelLabelDir) 21 | pixelLabelDir = uigetdir('','请选择导入的pixel标记/图像标记文件路径(文件夹)!'); 22 | if ~ischar(pixelLabelDir) 23 | warndlg('当前并没选择任何文件!','警告') 24 | return; 25 | end 26 | end 27 | 28 | imagesDir = pixelLabelDir; 29 | imagesLDir = pixelLabelDir; 30 | imds = imageDatastore(imagesDir,'FileExtensions','.jpg'); 31 | dataSource = groundTruthDataSource(imds.Files); 32 | lbds = imageDatastore(imagesLDir,'FileExtensions','.png'); 33 | labelData = table(lbds.Files,'VariableNames',{'PixelLabelData'}); 34 | 35 | if labelnames=="undefined" % 如果知道labelnames,直接输入参数省略下面判断,速度更快 36 | transformedObj = transform(lbds,@(x) unique(x));% transform, Introduced in R2019a 37 | labelVectors = []; 38 | while transformedObj.hasdata() 39 | labelVector = transformedObj.read(); 40 | newIdx = ~ismember(labelVector,labelVectors); 41 | labelVectors = [labelVectors;labelVector(newIdx)]; 42 | end 43 | labelnames = strings(length(labelVectors)-1,1);% 去除背景类别 44 | for i = 1:length(labelnames) 45 | labelnames(i) = "undefined_"+string(i); 46 | end 47 | end 48 | 49 | assert(~isempty(imds.Files),'origin images(.jpg) must not empty!'); 50 | assert(length(imds.Files)==length(lbds.Files),'origin images(.jpg) must equal to label images(.png)!'); 51 | a1 = extractBefore(string(imds.Files),'.'); 52 | a2 = extractBefore(string(lbds.Files),'.'); 53 | assert(all(a1==a2),'origin images(.jpg) and label images(.png) must be the same name!'); 54 | isUint8 = all(cellfun(@(x)validImage(x),lbds.Files)); 55 | assert(isUint8,'label images(.png) must one channel,uint8 type!'); 56 | 57 | ldc = labelDefinitionCreator; 58 | for i = 1:length(labelnames) 59 | addLabel(ldc,labelnames(i),labelType.PixelLabel); 60 | end 61 | labelDefs = create(ldc); 62 | 63 | gTruth = groundTruth(dataSource,labelDefs,labelData); 64 | imageLabeler % 自动打开app,Import Labels from workspace,手动导入gTruth即可 65 | 66 | function isvalid = validImage(filename) 67 | %功能:验证filename为uint8 单通道图像 68 | info = imfinfo(filename); 69 | isvalid = info.BitDepth==8; 70 | isvalid = isvalid & strcmp(info.ColorType,'grayscale'); 71 | end 72 | end -------------------------------------------------------------------------------- /pixel_to_matlab_old.m: -------------------------------------------------------------------------------- 1 | function gTruth = pixel_to_matlab_old(pixelLabelDir,labelnames) 2 | % 功能:多类别像素级语义分割标记导入,根据原图(jpg格式)和标记图(同名同大小的png格式, 3 | % uint8类型,从1开始的类别标记矩阵,0为背景类),生成groundTruth类型对象,最后可导入到imageLabeler APP中, 4 | % 原图和标记图要位于同一目录下 5 | % 6 | % 输入: 7 | % pixelLabelDir: 原图和标记图根目录,一副jpg原图对应一副png标记图 8 | % labelnames: 标记类型标签,cell array或者string数组类型,比如{'motobykes';'person'} 9 | % 输出: 10 | % gTruth: groundTruth类型标注信息文件,可直接导入到matlab imageLabeler APP中查看 11 | % 12 | % 注意:此函数支持R2017b及以上版本,其他高版本matlab请尽量使用pixel_to_matlab.m 13 | % 14 | % Example: 15 | % gTruth = pixel_to_matlab('imgsFolder/',{'motobykes';'person'}) 16 | % 17 | 18 | imagesDir = pixelLabelDir; 19 | imagesLDir = pixelLabelDir; 20 | imds = imageDatastore(imagesDir,'FileExtensions','.jpg'); 21 | dataSource = groundTruthDataSource(imds.Files); 22 | lbds = imageDatastore(imagesLDir,'FileExtensions','.png'); 23 | labelData = table(lbds.Files,'VariableNames',{'PixelLabelData'}); 24 | 25 | assert(~isempty(imds.Files),'origin images(.jpg) must not empty!'); 26 | assert(length(imds.Files)==length(lbds.Files),'origin images(.jpg) must equal to label images(.png)!'); 27 | a1 = extractBefore(string(imds.Files),'.'); 28 | a2 = extractBefore(string(lbds.Files),'.'); 29 | assert(all(a1==a2),'origin images(.jpg) and label images(.png) must be the same name!'); 30 | isUint8 = all(cellfun(@(x)validImage(x),lbds.Files)); 31 | assert(isUint8,'label images(.png) must one channel,uint8 type!'); 32 | 33 | Names = labelnames(:); % 比如{'motobykes';'person';}; 34 | nums = length(Names); 35 | Types = labelType(repmat({'PixelLabel'},nums,1)); 36 | pixelLabelID = mat2cell((1:nums)',ones(1,nums)); 37 | labelDefs = table(Names,Types, pixelLabelID, ... 38 | 'VariableNames',{'Name','Type','PixelLabelID'}); 39 | gTruth = groundTruth(dataSource,labelDefs,labelData); 40 | imageLabeler % 自动打开app,Import Labels from workspace,手动导入gTruth即可 41 | 42 | function isvalid = validImage(filename) 43 | %功能:验证filename为uint8 单通道图像 44 | info = imfinfo(filename); 45 | isvalid = info.BitDepth==8; 46 | isvalid = isvalid & strcmp(info.ColorType,'grayscale'); 47 | end 48 | end -------------------------------------------------------------------------------- /stopSignImages/image001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image001.jpg -------------------------------------------------------------------------------- /stopSignImages/image001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image001.png -------------------------------------------------------------------------------- /stopSignImages/image001.txt: -------------------------------------------------------------------------------- 1 | 3 2 | car 423 386 286 172 0 0 0 0 3 | car 136 379 253 140 0 0 0 0 4 | stop 857 312 42 48 0 0 0 0 5 | -------------------------------------------------------------------------------- /stopSignImages/image001.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image001.jpg 4 | F:\video\stopSignImages\image001.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 423 21 | 386 22 | 709 23 | 558 24 | 25 | 26 | 27 | car 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 136 33 | 379 34 | 389 35 | 519 36 | 37 | 38 | 39 | stop 40 | Unspecified 41 | 0 42 | 0 43 | 44 | 857 45 | 312 46 | 899 47 | 360 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /stopSignImages/image002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image002.jpg -------------------------------------------------------------------------------- /stopSignImages/image002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image002.png -------------------------------------------------------------------------------- /stopSignImages/image002.txt: -------------------------------------------------------------------------------- 1 | 1 2 | car 334 630 658 291 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image002.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image002.jpg 4 | F:\video\stopSignImages\image002.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 334 21 | 630 22 | 992 23 | 921 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image003.jpg -------------------------------------------------------------------------------- /stopSignImages/image003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image003.png -------------------------------------------------------------------------------- /stopSignImages/image003.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 1060 482 554 431 0 0 0 0 3 | person 868 384 155 514 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image003.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image003.jpg 4 | F:\video\stopSignImages\image003.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 1060 21 | 482 22 | 1614 23 | 913 24 | 25 | 26 | 27 | person 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 868 33 | 384 34 | 1023 35 | 898 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image004.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image004.jpg -------------------------------------------------------------------------------- /stopSignImages/image004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image004.png -------------------------------------------------------------------------------- /stopSignImages/image004.txt: -------------------------------------------------------------------------------- 1 | 4 2 | car 437 480 126 65 0 0 0 0 3 | car 764 501 117 59 0 0 0 0 4 | car 11 460 81 107 0 0 0 0 5 | car 1487 488 98 81 0 0 0 0 6 | -------------------------------------------------------------------------------- /stopSignImages/image004.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image004.jpg 4 | F:\video\stopSignImages\image004.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 437 21 | 480 22 | 563 23 | 545 24 | 25 | 26 | 27 | car 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 764 33 | 501 34 | 881 35 | 560 36 | 37 | 38 | 39 | car 40 | Unspecified 41 | 0 42 | 0 43 | 44 | 11 45 | 460 46 | 92 47 | 567 48 | 49 | 50 | 51 | car 52 | Unspecified 53 | 0 54 | 0 55 | 56 | 1487 57 | 488 58 | 1585 59 | 569 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /stopSignImages/image005.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image005.jpg -------------------------------------------------------------------------------- /stopSignImages/image005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image005.png -------------------------------------------------------------------------------- /stopSignImages/image005.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 515 423 288 179 0 0 0 0 3 | car 7 462 331 183 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image005.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image005.jpg 4 | F:\video\stopSignImages\image005.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 515 21 | 423 22 | 803 23 | 602 24 | 25 | 26 | 27 | car 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 7 33 | 462 34 | 338 35 | 645 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image006.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image006.jpg -------------------------------------------------------------------------------- /stopSignImages/image006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image006.png -------------------------------------------------------------------------------- /stopSignImages/image006.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 1202 421 431 386 0 0 0 0 3 | stop 1043 349 69 74 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image006.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image006.jpg 4 | F:\video\stopSignImages\image006.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 1202 21 | 421 22 | 1633 23 | 807 24 | 25 | 26 | 27 | stop 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 1043 33 | 349 34 | 1112 35 | 423 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image007.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image007.jpg -------------------------------------------------------------------------------- /stopSignImages/image007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image007.png -------------------------------------------------------------------------------- /stopSignImages/image007.txt: -------------------------------------------------------------------------------- 1 | 4 2 | car 297 392 283 227 0 0 0 0 3 | car 637 403 81 59 0 0 0 0 4 | car 907 408 68 48 0 0 0 0 5 | stop 1293 312 72 59 0 0 0 0 6 | -------------------------------------------------------------------------------- /stopSignImages/image007.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image007.jpg 4 | F:\video\stopSignImages\image007.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 297 21 | 392 22 | 580 23 | 619 24 | 25 | 26 | 27 | car 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 637 33 | 403 34 | 718 35 | 462 36 | 37 | 38 | 39 | car 40 | Unspecified 41 | 0 42 | 0 43 | 44 | 907 45 | 408 46 | 975 47 | 456 48 | 49 | 50 | 51 | stop 52 | Unspecified 53 | 0 54 | 0 55 | 56 | 1293 57 | 312 58 | 1365 59 | 371 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /stopSignImages/image008.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image008.jpg -------------------------------------------------------------------------------- /stopSignImages/image008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image008.png -------------------------------------------------------------------------------- /stopSignImages/image008.txt: -------------------------------------------------------------------------------- 1 | 3 2 | car 129 379 79 59 0 0 0 0 3 | car 428 377 70 50 0 0 0 0 4 | stop 799 290 74 54 0 0 0 0 5 | -------------------------------------------------------------------------------- /stopSignImages/image008.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image008.jpg 4 | F:\video\stopSignImages\image008.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 129 21 | 379 22 | 208 23 | 438 24 | 25 | 26 | 27 | car 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 428 33 | 377 34 | 498 35 | 427 36 | 37 | 38 | 39 | stop 40 | Unspecified 41 | 0 42 | 0 43 | 44 | 799 45 | 290 46 | 873 47 | 344 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /stopSignImages/image009.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image009.jpg -------------------------------------------------------------------------------- /stopSignImages/image009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image009.png -------------------------------------------------------------------------------- /stopSignImages/image009.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 253 349 75 54 0 0 0 0 3 | stop 639 255 66 63 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image009.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image009.jpg 4 | F:\video\stopSignImages\image009.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 253 21 | 349 22 | 328 23 | 403 24 | 25 | 26 | 27 | stop 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 639 33 | 255 34 | 705 35 | 318 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image010.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image010.jpg -------------------------------------------------------------------------------- /stopSignImages/image010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image010.png -------------------------------------------------------------------------------- /stopSignImages/image010.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 321 200 305 271 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image010.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image010.jpg 4 | F:\video\stopSignImages\image010.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 321 21 | 200 22 | 626 23 | 471 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image011.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image011.jpg -------------------------------------------------------------------------------- /stopSignImages/image011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image011.png -------------------------------------------------------------------------------- /stopSignImages/image011.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 1058 386 504 379 0 0 0 0 3 | stop 866 13 275 242 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image011.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image011.jpg 4 | F:\video\stopSignImages\image011.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 1058 21 | 386 22 | 1562 23 | 765 24 | 25 | 26 | 27 | stop 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 866 33 | 13 34 | 1141 35 | 255 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image012.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image012.jpg -------------------------------------------------------------------------------- /stopSignImages/image012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image012.png -------------------------------------------------------------------------------- /stopSignImages/image012.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 556 200 147 136 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image012.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image012.jpg 4 | F:\video\stopSignImages\image012.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 920 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 556 21 | 200 22 | 703 23 | 336 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image013.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image013.jpg -------------------------------------------------------------------------------- /stopSignImages/image013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image013.png -------------------------------------------------------------------------------- /stopSignImages/image013.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 416 285 313 341 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image013.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image013.jpg 4 | F:\video\stopSignImages\image013.jpg 5 | 6 | Unknow 7 | 8 | 9 | 968 10 | 1296 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 416 21 | 285 22 | 729 23 | 626 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image014.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image014.jpg -------------------------------------------------------------------------------- /stopSignImages/image014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image014.png -------------------------------------------------------------------------------- /stopSignImages/image014.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 367 316 359 396 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image014.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image014.jpg 4 | F:\video\stopSignImages\image014.jpg 5 | 6 | Unknow 7 | 8 | 9 | 968 10 | 1296 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 367 21 | 316 22 | 726 23 | 712 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image015.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image015.jpg -------------------------------------------------------------------------------- /stopSignImages/image015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image015.png -------------------------------------------------------------------------------- /stopSignImages/image015.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 797 839 284 144 0 0 0 0 3 | stop 693 403 173 154 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image015.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image015.jpg 4 | F:\video\stopSignImages\image015.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 797 21 | 839 22 | 1081 23 | 983 24 | 25 | 26 | 27 | stop 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 693 33 | 403 34 | 866 35 | 557 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image016.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image016.jpg -------------------------------------------------------------------------------- /stopSignImages/image016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image016.png -------------------------------------------------------------------------------- /stopSignImages/image016.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 650 571 47 52 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image016.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image016.jpg 4 | F:\video\stopSignImages\image016.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 650 21 | 571 22 | 697 23 | 623 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image017.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image017.jpg -------------------------------------------------------------------------------- /stopSignImages/image017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image017.png -------------------------------------------------------------------------------- /stopSignImages/image017.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 420 616 45 52 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image017.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image017.jpg 4 | F:\video\stopSignImages\image017.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 420 21 | 616 22 | 465 23 | 668 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image018.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image018.jpg -------------------------------------------------------------------------------- /stopSignImages/image018.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image018.png -------------------------------------------------------------------------------- /stopSignImages/image018.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 652 469 48 45 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image018.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image018.jpg 4 | F:\video\stopSignImages\image018.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 652 21 | 469 22 | 700 23 | 514 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image019.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image019.jpg -------------------------------------------------------------------------------- /stopSignImages/image019.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image019.png -------------------------------------------------------------------------------- /stopSignImages/image019.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 640 379 199 216 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image019.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image019.jpg 4 | F:\video\stopSignImages\image019.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 640 21 | 379 22 | 839 23 | 595 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image020.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image020.jpg -------------------------------------------------------------------------------- /stopSignImages/image020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image020.png -------------------------------------------------------------------------------- /stopSignImages/image020.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 550 381 278 107 0 0 0 0 3 | car 882 377 273 99 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image020.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image020.jpg 4 | F:\video\stopSignImages\image020.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 550 21 | 381 22 | 828 23 | 488 24 | 25 | 26 | 27 | car 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 882 33 | 377 34 | 1155 35 | 476 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image021.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image021.jpg -------------------------------------------------------------------------------- /stopSignImages/image021.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image021.png -------------------------------------------------------------------------------- /stopSignImages/image021.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 591 246 173 178 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image021.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image021.jpg 4 | F:\video\stopSignImages\image021.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 591 21 | 246 22 | 764 23 | 424 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image022.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image022.jpg -------------------------------------------------------------------------------- /stopSignImages/image022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image022.png -------------------------------------------------------------------------------- /stopSignImages/image022.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 946 597 436 149 0 0 0 0 3 | stop 503 474 50 61 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image022.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image022.jpg 4 | F:\video\stopSignImages\image022.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 946 21 | 597 22 | 1382 23 | 746 24 | 25 | 26 | 27 | stop 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 503 33 | 474 34 | 553 35 | 535 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image023.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image023.jpg -------------------------------------------------------------------------------- /stopSignImages/image023.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image023.png -------------------------------------------------------------------------------- /stopSignImages/image023.txt: -------------------------------------------------------------------------------- 1 | 1 2 | car 811 559 538 194 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image023.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image023.jpg 4 | F:\video\stopSignImages\image023.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 811 21 | 559 22 | 1349 23 | 753 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image024.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image024.jpg -------------------------------------------------------------------------------- /stopSignImages/image024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image024.png -------------------------------------------------------------------------------- /stopSignImages/image024.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 527 400 42 93 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image024.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image024.jpg 4 | F:\video\stopSignImages\image024.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 527 21 | 400 22 | 569 23 | 493 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image025.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image025.jpg -------------------------------------------------------------------------------- /stopSignImages/image025.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image025.png -------------------------------------------------------------------------------- /stopSignImages/image025.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 977 481 182 85 0 0 0 0 3 | stop 752 339 78 87 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image025.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image025.jpg 4 | F:\video\stopSignImages\image025.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 977 21 | 481 22 | 1159 23 | 566 24 | 25 | 26 | 27 | stop 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 752 33 | 339 34 | 830 35 | 426 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image026.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image026.jpg -------------------------------------------------------------------------------- /stopSignImages/image026.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image026.png -------------------------------------------------------------------------------- /stopSignImages/image026.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 522 287 156 156 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image026.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image026.jpg 4 | F:\video\stopSignImages\image026.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 522 21 | 287 22 | 678 23 | 443 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image027.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image027.jpg -------------------------------------------------------------------------------- /stopSignImages/image027.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image027.png -------------------------------------------------------------------------------- /stopSignImages/image027.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 531 192 178 237 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image027.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image027.jpg 4 | F:\video\stopSignImages\image027.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 531 21 | 192 22 | 709 23 | 429 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image028.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image028.jpg -------------------------------------------------------------------------------- /stopSignImages/image028.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image028.png -------------------------------------------------------------------------------- /stopSignImages/image028.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 678 372 157 211 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image028.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image028.jpg 4 | F:\video\stopSignImages\image028.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 678 21 | 372 22 | 835 23 | 583 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image029.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image029.jpg -------------------------------------------------------------------------------- /stopSignImages/image029.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image029.png -------------------------------------------------------------------------------- /stopSignImages/image029.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 704 429 98 95 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image029.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image029.jpg 4 | F:\video\stopSignImages\image029.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 704 21 | 429 22 | 802 23 | 524 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image030.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image030.jpg -------------------------------------------------------------------------------- /stopSignImages/image030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image030.png -------------------------------------------------------------------------------- /stopSignImages/image030.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 681 452 95 88 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image030.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image030.jpg 4 | F:\video\stopSignImages\image030.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 681 21 | 452 22 | 776 23 | 540 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image031.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image031.jpg -------------------------------------------------------------------------------- /stopSignImages/image031.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image031.png -------------------------------------------------------------------------------- /stopSignImages/image031.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 664 377 180 170 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image031.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image031.jpg 4 | F:\video\stopSignImages\image031.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 664 21 | 377 22 | 844 23 | 547 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image032.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image032.jpg -------------------------------------------------------------------------------- /stopSignImages/image032.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image032.png -------------------------------------------------------------------------------- /stopSignImages/image032.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 664 301 249 336 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image032.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image032.jpg 4 | F:\video\stopSignImages\image032.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1504 10 | 1000 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 664 21 | 301 22 | 913 23 | 637 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image033.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image033.jpg -------------------------------------------------------------------------------- /stopSignImages/image033.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image033.png -------------------------------------------------------------------------------- /stopSignImages/image033.txt: -------------------------------------------------------------------------------- 1 | 2 2 | stop 737 429 61 72 0 0 0 0 3 | stop 995 519 111 180 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image033.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image033.jpg 4 | F:\video\stopSignImages\image033.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 1224 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 737 21 | 429 22 | 798 23 | 501 24 | 25 | 26 | 27 | stop 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 995 33 | 519 34 | 1106 35 | 699 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image034.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image034.jpg -------------------------------------------------------------------------------- /stopSignImages/image034.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image034.png -------------------------------------------------------------------------------- /stopSignImages/image034.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 755 432 150 278 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image034.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image034.jpg 4 | F:\video\stopSignImages\image034.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 1224 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 755 21 | 432 22 | 905 23 | 710 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image035.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image035.jpg -------------------------------------------------------------------------------- /stopSignImages/image035.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image035.png -------------------------------------------------------------------------------- /stopSignImages/image035.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 282 809 568 415 0 0 0 0 3 | stop 360 545 166 606 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image035.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image035.jpg 4 | F:\video\stopSignImages\image035.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 1224 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 282 21 | 809 22 | 850 23 | 1224 24 | 25 | 26 | 27 | stop 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 360 33 | 545 34 | 526 35 | 1151 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image036.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image036.jpg -------------------------------------------------------------------------------- /stopSignImages/image036.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image036.png -------------------------------------------------------------------------------- /stopSignImages/image036.txt: -------------------------------------------------------------------------------- 1 | 3 2 | car 940 244 664 368 0 0 0 0 3 | car 1096 327 528 377 0 0 0 0 4 | stop 703 275 263 598 0 0 0 0 5 | -------------------------------------------------------------------------------- /stopSignImages/image036.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image036.jpg 4 | F:\video\stopSignImages\image036.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 1224 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 940 21 | 244 22 | 1604 23 | 612 24 | 25 | 26 | 27 | car 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 1096 33 | 327 34 | 1624 35 | 704 36 | 37 | 38 | 39 | stop 40 | Unspecified 41 | 0 42 | 0 43 | 44 | 703 45 | 275 46 | 966 47 | 873 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /stopSignImages/image037.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image037.jpg -------------------------------------------------------------------------------- /stopSignImages/image037.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image037.png -------------------------------------------------------------------------------- /stopSignImages/image037.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 729 150 467 624 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image037.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image037.jpg 4 | F:\video\stopSignImages\image037.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 1224 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 729 21 | 150 22 | 1196 23 | 774 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /stopSignImages/image038.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image038.jpg -------------------------------------------------------------------------------- /stopSignImages/image038.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image038.png -------------------------------------------------------------------------------- /stopSignImages/image038.txt: -------------------------------------------------------------------------------- 1 | 2 2 | stop 604 319 139 226 0 0 0 0 3 | stop 1451 583 182 571 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image038.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image038.jpg 4 | F:\video\stopSignImages\image038.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 1224 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 604 21 | 319 22 | 743 23 | 545 24 | 25 | 26 | 27 | stop 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 1451 33 | 583 34 | 1633 35 | 1154 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image039.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image039.jpg -------------------------------------------------------------------------------- /stopSignImages/image039.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image039.png -------------------------------------------------------------------------------- /stopSignImages/image039.txt: -------------------------------------------------------------------------------- 1 | 2 2 | car 12 34 1543 781 0 0 0 0 3 | stop 494 69 519 1105 0 0 0 0 4 | -------------------------------------------------------------------------------- /stopSignImages/image039.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image039.jpg 4 | F:\video\stopSignImages\image039.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 1224 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 12 21 | 34 22 | 1555 23 | 815 24 | 25 | 26 | 27 | stop 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 494 33 | 69 34 | 1013 35 | 1174 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /stopSignImages/image040.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image040.jpg -------------------------------------------------------------------------------- /stopSignImages/image040.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image040.png -------------------------------------------------------------------------------- /stopSignImages/image040.txt: -------------------------------------------------------------------------------- 1 | 3 2 | car 589 968 279 99 0 0 0 0 3 | car 1056 939 61 53 0 0 0 0 4 | stop 865 826 64 67 0 0 0 0 5 | -------------------------------------------------------------------------------- /stopSignImages/image040.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image040.jpg 4 | F:\video\stopSignImages\image040.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 1224 11 | 3 12 | 13 | 0 14 | 15 | car 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 589 21 | 968 22 | 868 23 | 1067 24 | 25 | 26 | 27 | car 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 1056 33 | 939 34 | 1117 35 | 992 36 | 37 | 38 | 39 | stop 40 | Unspecified 41 | 0 42 | 0 43 | 44 | 865 45 | 826 46 | 929 47 | 893 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /stopSignImages/image041.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image041.jpg -------------------------------------------------------------------------------- /stopSignImages/image041.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/stopSignImages/image041.png -------------------------------------------------------------------------------- /stopSignImages/image041.txt: -------------------------------------------------------------------------------- 1 | 1 2 | stop 827 266 250 357 0 0 0 0 3 | -------------------------------------------------------------------------------- /stopSignImages/image041.xml: -------------------------------------------------------------------------------- 1 | 2 | stopSignImages 3 | image041.jpg 4 | F:\video\stopSignImages\image041.jpg 5 | 6 | Unknow 7 | 8 | 9 | 1632 10 | 1224 11 | 3 12 | 13 | 0 14 | 15 | stop 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 827 21 | 266 22 | 1077 23 | 623 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /table_to_gTruth.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/table_to_gTruth.m -------------------------------------------------------------------------------- /txt_to_matlab.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/txt_to_matlab.m -------------------------------------------------------------------------------- /xml_io_tools/code/base64decode.m: -------------------------------------------------------------------------------- 1 | function y = base64decode(x, outfname, alg) 2 | %BASE64DECODE Perform base64 decoding on a string. 3 | % 4 | % INPUT: 5 | % x - block of data to be decoded. Can be a string or a numeric 6 | % vector containing integers in the range 0-255. Any character 7 | % not part of the 65-character base64 subset set is silently 8 | % ignored. Characters occuring after a '=' padding character are 9 | % never decoded. If the length of the string to decode (after 10 | % ignoring non-base64 chars) is not a multiple of 4, then a 11 | % warning is generated. 12 | % 13 | % outfname - if provided the binary date from decoded string will be 14 | % saved into a file. Since Base64 coding is often used to embbed 15 | % binary data in xml files, this option can be used to extract and 16 | % save them. 17 | % 18 | % alg - Algorithm to use: can take values 'java' or 'matlab'. Optional 19 | % variable defaulting to 'java' which is a little faster. If 20 | % 'java' is chosen than core of the code is performed by a call to 21 | % a java library. Optionally all operations can be performed using 22 | % matleb code. 23 | % 24 | % OUTPUT: 25 | % y - array of binary data returned as uint8 26 | % 27 | % This function is used to decode strings from the Base64 encoding specified 28 | % in RFC 2045 - MIME (Multipurpose Internet Mail Extensions). The Base64 29 | % encoding is designed to represent arbitrary sequences of octets in a form 30 | % that need not be humanly readable. A 65-character subset ([A-Za-z0-9+/=]) 31 | % of US-ASCII is used, enabling 6 bits to be represented per printable 32 | % character. 33 | % 34 | % See also BASE64ENCODE. 35 | % 36 | % Written by Jarek Tuszynski, SAIC, jaroslaw.w.tuszynski_at_saic.com 37 | % 38 | % Matlab version based on 2004 code by Peter J. Acklam 39 | % E-mail: pjacklam@online.no 40 | % URL: http://home.online.no/~pjacklam 41 | % http://home.online.no/~pjacklam/matlab/software/util/datautil/base64encode.m 42 | 43 | if nargin<3, alg='java'; end 44 | if nargin<2, outfname=''; end 45 | 46 | %% if x happen to be a filename than read the file 47 | if (numel(x)<256) 48 | if (exist(x, 'file')==2) 49 | fid = fopen(x,'rb'); 50 | x = fread(fid, 'uint8'); 51 | fclose(fid); 52 | end 53 | end 54 | x = uint8(x(:)); % unify format 55 | 56 | %% Perform conversion 57 | switch (alg) 58 | case 'java' 59 | base64 = org.apache.commons.codec.binary.Base64; 60 | y = base64.decode(x); 61 | y = mod(int16(y),256); % convert from int8 to uint8 62 | case 'matlab' 63 | %% Perform the mapping 64 | % A-Z -> 0 - 25 65 | % a-z -> 26 - 51 66 | % 0-9 -> 52 - 61 67 | % + - -> 62 '-' is URL_SAFE alternative 68 | % / _ -> 63 '_' is URL_SAFE alternative 69 | map = uint8(zeros(1,256)+65); 70 | map(uint8(['A':'Z', 'a':'z', '0':'9', '+/=']))= 0:64; 71 | map(uint8('-_'))= 62:63; % URL_SAFE alternatives 72 | x = map(x); % mapping 73 | 74 | x(x>64)=[]; % remove non-base64 chars 75 | if rem(numel(x), 4) 76 | warning('Length of base64 data not a multiple of 4; padding input.'); 77 | end 78 | x(x==64)=[]; % remove padding characters 79 | 80 | %% add padding and reshape 81 | nebytes = length(x); % number of encoded bytes 82 | nchunks = ceil(nebytes/4); % number of chunks/groups 83 | if rem(nebytes, 4)>0 84 | x(end+1 : 4*nchunks) = 0; % add padding 85 | end 86 | x = reshape(uint8(x), 4, nchunks); 87 | y = repmat(uint8(0), 3, nchunks); % for the decoded data 88 | 89 | %% Rearrange every 4 bytes into 3 bytes 90 | % 00aaaaaa 00bbbbbb 00cccccc 00dddddd 91 | % to form 92 | % aaaaaabb bbbbcccc ccdddddd 93 | y(1,:) = bitshift(x(1,:), 2); % 6 highest bits of y(1,:) 94 | y(1,:) = bitor(y(1,:), bitshift(x(2,:), -4)); % 2 lowest bits of y(1,:) 95 | y(2,:) = bitshift(x(2,:), 4); % 4 highest bits of y(2,:) 96 | y(2,:) = bitor(y(2,:), bitshift(x(3,:), -2)); % 4 lowest bits of y(2,:) 97 | y(3,:) = bitshift(x(3,:), 6); % 2 highest bits of y(3,:) 98 | y(3,:) = bitor(y(3,:), x(4,:)); % 6 lowest bits of y(3,:) 99 | 100 | %% remove extra padding 101 | switch rem(nebytes, 4) 102 | case 2 103 | y = y(1:end-2); 104 | case 3 105 | y = y(1:end-1); 106 | end 107 | end 108 | 109 | %% reshape to a row vector and make it a character array 110 | y = uint8(reshape(y, 1, numel(y))); 111 | 112 | %% save to file if needed 113 | if ~isempty(outfname) 114 | fid = fopen(outfname,'wb'); 115 | fwrite(fid, y, 'uint8'); 116 | fclose(fid); 117 | end 118 | -------------------------------------------------------------------------------- /xml_io_tools/code/base64encode.m: -------------------------------------------------------------------------------- 1 | function y = base64encode(x, alg, isChunked, url_safe) 2 | %BASE64ENCODE Perform base64 encoding on a string. 3 | % INPUT: 4 | % x - block of data to be encoded. Can be a string or a numeric 5 | % vector containing integers in the range 0-255. 6 | % alg - Algorithm to use: can take values 'java' or 'matlab'. Optional 7 | % variable defaulting to 'java' which is a little faster. If 8 | % 'java' is chosen than core of the code is performed by a call to 9 | % a java library. Optionally all operations can be performed using 10 | % matleb code. 11 | % isChunked - encode output into 76 character blocks. The returned 12 | % encoded string is broken into lines of no more than 13 | % 76 characters each, and each line will end with EOL. Notice that 14 | % if resulting string is saved as part of an xml file, those EOL's 15 | % are often stripped by xmlwrite funtrion prior to saving. 16 | % url_safe - use Modified Base64 for URL applications ('base64url' 17 | % encoding) "Base64 alphabet" ([A-Za-z0-9-_=]). 18 | % 19 | % 20 | % OUTPUT: 21 | % y - character array using only "Base64 alphabet" characters 22 | % 23 | % This function may be used to encode strings into the Base64 encoding 24 | % specified in RFC 2045 - MIME (Multipurpose Internet Mail Extensions). 25 | % The Base64 encoding is designed to represent arbitrary sequences of 26 | % octets in a form that need not be humanly readable. A 65-character 27 | % subset ([A-Za-z0-9+/=]) of US-ASCII is used, enabling 6 bits to be 28 | % represented per printable character. 29 | % 30 | % See also BASE64DECODE. 31 | % 32 | % Written by Jarek Tuszynski, SAIC, jaroslaw.w.tuszynski_at_saic.com 33 | % 34 | % Matlab version based on 2004 code by Peter J. Acklam 35 | % E-mail: pjacklam@online.no 36 | % URL: http://home.online.no/~pjacklam 37 | % http://home.online.no/~pjacklam/matlab/software/util/datautil/base64encode.m 38 | 39 | if nargin<2, alg='java'; end 40 | if nargin<3, isChunked=false; end 41 | if ~islogical(isChunked) 42 | if isnumeric(isChunked) 43 | isChunked=(isChunked>0); 44 | else 45 | isChunked=false; 46 | end 47 | end 48 | if nargin<4, url_safe=false; end 49 | if ~islogical(url_safe) 50 | if isnumeric(url_safe) 51 | url_safe=(url_safe>0); 52 | else 53 | url_safe=false; 54 | end 55 | end 56 | 57 | 58 | %% if x happen to be a filename than read the file 59 | if (numel(x)<256) 60 | if (exist(x, 'file')==2) 61 | fid = fopen(x,'rb'); 62 | x = fread(fid, 'uint8'); % read image file as a raw binary 63 | fclose(fid); 64 | end 65 | end 66 | 67 | %% Perform conversion 68 | switch (alg) 69 | case 'java' 70 | base64 = org.apache.commons.codec.binary.Base64; 71 | y = base64.encodeBase64(x, isChunked); 72 | if url_safe 73 | y = strrep(y,'=','-'); 74 | y = strrep(y,'/','_'); 75 | end 76 | 77 | case 'matlab' 78 | 79 | %% add padding if necessary, to make the length of x a multiple of 3 80 | x = uint8(x(:)); 81 | ndbytes = length(x); % number of decoded bytes 82 | nchunks = ceil(ndbytes / 3); % number of chunks/groups 83 | if rem(ndbytes, 3)>0 84 | x(end+1 : 3*nchunks) = 0; % add padding 85 | end 86 | x = reshape(x, [3, nchunks]); % reshape the data 87 | y = repmat(uint8(0), 4, nchunks); % for the encoded data 88 | 89 | %% Split up every 3 bytes into 4 pieces 90 | % aaaaaabb bbbbcccc ccdddddd 91 | % to form 92 | % 00aaaaaa 00bbbbbb 00cccccc 00dddddd 93 | y(1,:) = bitshift(x(1,:), -2); % 6 highest bits of x(1,:) 94 | y(2,:) = bitshift(bitand(x(1,:), 3), 4); % 2 lowest bits of x(1,:) 95 | y(2,:) = bitor(y(2,:), bitshift(x(2,:), -4)); % 4 highest bits of x(2,:) 96 | y(3,:) = bitshift(bitand(x(2,:), 15), 2); % 4 lowest bits of x(2,:) 97 | y(3,:) = bitor(y(3,:), bitshift(x(3,:), -6)); % 2 highest bits of x(3,:) 98 | y(4,:) = bitand(x(3,:), 63); % 6 lowest bits of x(3,:) 99 | 100 | %% Perform the mapping 101 | % 0 - 25 -> A-Z 102 | % 26 - 51 -> a-z 103 | % 52 - 61 -> 0-9 104 | % 62 -> + 105 | % 63 -> / 106 | map = ['A':'Z', 'a':'z', '0':'9', '+/']; 107 | if (url_safe), map(63:64)='-_'; end 108 | y = map(y(:)+1); 109 | 110 | %% Add padding if necessary. 111 | npbytes = 3 * nchunks - ndbytes; % number of padding bytes 112 | if npbytes>0 113 | y(end-npbytes+1 : end) = '='; % '=' is used for padding 114 | end 115 | 116 | %% break into lines with length LineLength 117 | if (isChunked) 118 | eol = sprintf('\n'); 119 | nebytes = numel(y); 120 | nlines = ceil(nebytes / 76); % number of lines 121 | neolbytes = length(eol); % number of bytes in eol string 122 | 123 | % pad data so it becomes a multiple of 76 elements 124 | y(nebytes + 1 : 76 * nlines) = 0; 125 | y = reshape(y, 76, nlines); 126 | 127 | % insert eol strings 128 | y(end + 1 : end + neolbytes, :) = eol(:, ones(1, nlines)); 129 | 130 | % remove padding, but keep the last eol string 131 | m = nebytes + neolbytes * (nlines - 1); 132 | n = (76+neolbytes)*nlines - neolbytes; 133 | y(m+1 : n) = []; 134 | end 135 | end 136 | 137 | %% reshape to a row vector and make it a character array 138 | y = char(reshape(y, 1, numel(y))); 139 | -------------------------------------------------------------------------------- /xml_io_tools/code/gen_object_display.m: -------------------------------------------------------------------------------- 1 | function gen_object_display( obj_struct,indent ) 2 | % 3 | % gen_object_display - general function to display an object's content 4 | % 5 | % format: gen_object_display( obj_struct,indent ) 6 | % 7 | % input: obj_struct - a copy of the object stored inside a structure 8 | % indent - amount of "indent" when printing to the screen 9 | % 10 | % output: to the screen 11 | % 12 | % example: gen_object_display( struct( my_object_handle) ); 13 | % gen_object_display( ny_structure ); 14 | % 15 | % Correction History: 16 | % 2006-11-01 - Jarek Tuszynski - added support for struct arrays 17 | 18 | %% handle insufficient input 19 | if ( nargin == 0 ) 20 | help gen_object_display; 21 | return; 22 | elseif (nargin == 1) 23 | indent = 1; 24 | end 25 | 26 | %% check input for errors 27 | % if ~isstruct( obj_struct ) 28 | % fprintf( '\n\n\tMake sure that ''obj_struct'' is a struct type\n' ); 29 | % return 30 | % end 31 | 32 | % if (iscell( obj_struct )) 33 | % for i =1:length(obj_struct) 34 | % gen_object_display( obj_struct{i},indent + 2 ); 35 | % end 36 | % return 37 | % end 38 | if ~isstruct( obj_struct ) 39 | space = sprintf( sprintf( '%%%ds',indent ),' ' ); 40 | fprintf( ' %s', space); 41 | disp(obj_struct); 42 | return 43 | end 44 | 45 | % find the longest name 46 | field_list = fieldnames( obj_struct ); 47 | max_strlen = 0; 48 | for idx = 1:length( field_list ) 49 | max_strlen = max( max_strlen,length(field_list{idx}) ); 50 | end 51 | 52 | %% setup the display format (spacing) 53 | space = sprintf( sprintf( '%%%ds',indent ),' ' ); 54 | name_format = sprintf( ' %s%%%ds: ', space, max_strlen ); 55 | name_format2= sprintf( ' %s%%%ds', space, max_strlen ); 56 | max_displen = 110 - max_strlen - indent; 57 | 58 | %% display each field, if it is not too long 59 | for iItem = 1:length( obj_struct ) % loop added by JT 60 | for idx = 1:length( field_list ) 61 | 62 | % prepare field name to be displayed 63 | name = sprintf( name_format,field_list{idx} ); 64 | %temp = getfield( obj_struct,field_list{idx} ); % original by OG 65 | temp = obj_struct(iItem).(field_list{idx}); % modification by JT 66 | 67 | % proceed according the variable's type 68 | switch (1) 69 | case islogical( temp ), % case added by JT 70 | if isscalar(temp) 71 | if (temp) 72 | fprintf( '%strue\n',name ); 73 | else 74 | fprintf( '%sfalse\n',name ); 75 | end 76 | else 77 | fprintf( '%s[%dx%d logical]\n',name,size(temp,1),size(temp,2) ); 78 | end 79 | case ischar( temp ), 80 | if (length(temp) 137 | fprintf( '[No method to display type]' ); 138 | end 139 | fprintf( '\n' ); 140 | end 141 | end 142 | if (length(obj_struct)>1), fprintf('\n'); end % added by JT 143 | end % added by JT -------------------------------------------------------------------------------- /xml_io_tools/code/html/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Apples44%
Bannanas23%
Oranges13%
Other10%
21 |
-------------------------------------------------------------------------------- /xml_io_tools/code/html/xml_tutorial_script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/xml_io_tools/code/html/xml_tutorial_script.png -------------------------------------------------------------------------------- /xml_io_tools/code/html/xml_tutorial_script_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuixing158/imageLabeler-API/2a7772d27c93a7c2d9931780c6183a4848fba242/xml_io_tools/code/html/xml_tutorial_script_01.png -------------------------------------------------------------------------------- /xml_io_tools/code/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007, Jaroslaw Tuszynski 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /xml_io_tools/code/test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 4 | Hello World 5 | -------------------------------------------------------------------------------- /xml_io_tools/code/test_file.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | bbb 8 | 9 | ccc 10 | 11 | 5e3+2*i, Inf 12 | NaN, pi 13 | 14 | ee_e 15 | ff-f 16 | ggög 17 | xml tags are treated as ... 19 | ... text 20 | ]]> 21 | 22 | 23 | -------------------------------------------------------------------------------- /xml_io_tools/code/xml_read.m: -------------------------------------------------------------------------------- 1 | function [tree, RootName, DOMnode] = xml_read(xmlfile, Pref) 2 | %XML_READ reads xml files and converts them into Matlab's struct tree. 3 | % 4 | % DESCRIPTION 5 | % tree = xml_read(xmlfile) reads 'xmlfile' into data structure 'tree' 6 | % 7 | % tree = xml_read(xmlfile, Pref) reads 'xmlfile' into data structure 'tree' 8 | % according to your preferences 9 | % 10 | % [tree, RootName, DOMnode] = xml_read(xmlfile) get additional information 11 | % about XML file 12 | % 13 | % INPUT: 14 | % xmlfile URL or filename of xml file to read 15 | % Pref Preferences: 16 | % Pref.ItemName - default 'item' - name of a special tag used to itemize 17 | % cell arrays 18 | % Pref.ReadAttr - default true - allow reading attributes 19 | % Pref.ReadSpec - default true - allow reading special nodes 20 | % Pref.Str2Num - default 'smart' - convert strings that look like numbers 21 | % to numbers. Options: "always", "never", and "smart" 22 | % Pref.KeepNS - default true - keep or strip namespace info 23 | % Pref.NoCells - default true - force output to have no cell arrays 24 | % Pref.Debug - default false - show mode specific error messages 25 | % Pref.NumLevels- default infinity - how many recursive levels are 26 | % allowed. Can be used to speed up the function by prunning the tree. 27 | % Pref.RootOnly - default true - output variable 'tree' corresponds to 28 | % xml file root element, otherwise it correspond to the whole file. 29 | % Pref.CellItem - default 'true' - leave 'item' nodes in cell notation. 30 | % OUTPUT: 31 | % tree tree of structs and/or cell arrays corresponding to xml file 32 | % RootName XML tag name used for root (top level) node. 33 | % Optionally it can be a string cell array storing: Name of 34 | % root node, document "Processing Instructions" data and 35 | % document "comment" string 36 | % DOMnode output of xmlread 37 | % 38 | % DETAILS: 39 | % Function xml_read first calls MATLAB's xmlread function and than 40 | % converts its output ('Document Object Model' tree of Java objects) 41 | % to tree of MATLAB struct's. The output is in format of nested structs 42 | % and cells. In the output data structure field names are based on 43 | % XML tags, except in cases when tags produce illegal variable names. 44 | % 45 | % Several special xml node types result in special tags for fields of 46 | % 'tree' nodes: 47 | % - node.CONTENT - stores data section of the node if other fields are 48 | % present. Usually data section is stored directly in 'node'. 49 | % - node.ATTRIBUTE.name - stores node's attribute called 'name'. 50 | % - node.COMMENT - stores node's comment section (string). For global 51 | % comments see "RootName" output variable. 52 | % - node.CDATA_SECTION - stores node's CDATA section (string). 53 | % - node.PROCESSING_INSTRUCTIONS - stores "processing instruction" child 54 | % node. For global "processing instructions" see "RootName" output variable. 55 | % - other special node types like: document fragment nodes, document type 56 | % nodes, entity nodes, notation nodes and processing instruction nodes 57 | % will be treated like regular nodes 58 | % 59 | % EXAMPLES: 60 | % MyTree=[]; 61 | % MyTree.MyNumber = 13; 62 | % MyTree.MyString = 'Hello World'; 63 | % xml_write('test.xml', MyTree); 64 | % [tree treeName] = xml_read ('test.xml'); 65 | % disp(treeName) 66 | % gen_object_display() 67 | % % See also xml_examples.m 68 | % 69 | % See also: 70 | % xml_write, xmlread, xmlwrite 71 | % 72 | % Written by Jarek Tuszynski, SAIC, jaroslaw.w.tuszynski_at_saic.com 73 | % References: 74 | % - Function inspired by Example 3 found in xmlread function. 75 | % - Output data structures inspired by xml_toolbox structures. 76 | 77 | %% default preferences 78 | DPref.TableName = {'tr','td'}; % name of a special tags used to itemize 2D cell arrays 79 | DPref.ItemName = 'item'; % name of a special tag used to itemize 1D cell arrays 80 | DPref.CellItem = false; % leave 'item' nodes in cell notation 81 | DPref.ReadAttr = true; % allow reading attributes 82 | DPref.ReadSpec = true; % allow reading special nodes: comments, CData, etc. 83 | DPref.KeepNS = true; % Keep or strip namespace info 84 | DPref.Str2Num = 'smart';% convert strings that look like numbers to numbers 85 | DPref.NoCells = true; % force output to have no cell arrays 86 | DPref.NumLevels = 1e10; % number of recurence levels 87 | DPref.PreserveSpace = false; % Preserve or delete spaces at the beggining and the end of stings? 88 | RootOnly = true; % return root node with no top level special nodes 89 | Debug = false; % show specific errors (true) or general (false)? 90 | tree = []; 91 | RootName = []; 92 | 93 | %% Check Matlab Version 94 | v = ver('MATLAB'); 95 | version = str2double(regexp(v.Version, '\d.\d','match','once')); 96 | if (version<7.1) 97 | error('Your MATLAB version is too old. You need version 7.1 or newer.'); 98 | end 99 | 100 | %% read user preferences 101 | if (nargin>1) 102 | if (isfield(Pref, 'TableName')), DPref.TableName = Pref.TableName; end 103 | if (isfield(Pref, 'ItemName' )), DPref.ItemName = Pref.ItemName; end 104 | if (isfield(Pref, 'CellItem' )), DPref.CellItem = Pref.CellItem; end 105 | if (isfield(Pref, 'Str2Num' )), DPref.Str2Num = Pref.Str2Num ; end 106 | if (isfield(Pref, 'NoCells' )), DPref.NoCells = Pref.NoCells ; end 107 | if (isfield(Pref, 'NumLevels')), DPref.NumLevels = Pref.NumLevels; end 108 | if (isfield(Pref, 'ReadAttr' )), DPref.ReadAttr = Pref.ReadAttr; end 109 | if (isfield(Pref, 'ReadSpec' )), DPref.ReadSpec = Pref.ReadSpec; end 110 | if (isfield(Pref, 'KeepNS' )), DPref.KeepNS = Pref.KeepNS; end 111 | if (isfield(Pref, 'RootOnly' )), RootOnly = Pref.RootOnly; end 112 | if (isfield(Pref, 'Debug' )), Debug = Pref.Debug ; end 113 | if (isfield(Pref, 'PreserveSpace')), DPref.PreserveSpace = Pref.PreserveSpace; end 114 | end 115 | if ischar(DPref.Str2Num), % convert from character description to numbers 116 | DPref.Str2Num = find(strcmpi(DPref.Str2Num, {'never', 'smart', 'always'}))-1; 117 | if isempty(DPref.Str2Num), DPref.Str2Num=1; end % 1-smart by default 118 | end 119 | 120 | %% read xml file using Matlab function 121 | if isa(xmlfile, 'org.apache.xerces.dom.DeferredDocumentImpl'); 122 | % if xmlfile is a DOMnode than skip the call to xmlread 123 | try 124 | try 125 | DOMnode = xmlfile; 126 | catch ME 127 | error('Invalid DOM node: \n%s.', getReport(ME)); 128 | end 129 | catch %#ok catch for mablab versions prior to 7.5 130 | error('Invalid DOM node. \n'); 131 | end 132 | else % we assume xmlfile is a filename 133 | if (Debug) % in debuging mode crashes are allowed 134 | DOMnode = xmlread(xmlfile); 135 | else % in normal mode crashes are not allowed 136 | try 137 | try 138 | DOMnode = xmlread(xmlfile); 139 | catch ME 140 | error('Failed to read XML file %s: \n%s',xmlfile, getReport(ME)); 141 | end 142 | catch %#ok catch for mablab versions prior to 7.5 143 | error('Failed to read XML file %s\n',xmlfile); 144 | end 145 | end 146 | end 147 | Node = DOMnode.getFirstChild; 148 | 149 | %% Find the Root node. Also store data from Global Comment and Processing 150 | % Instruction nodes, if any. 151 | GlobalTextNodes = cell(1,3); 152 | GlobalProcInst = []; 153 | GlobalComment = []; 154 | GlobalDocType = []; 155 | while (~isempty(Node)) 156 | if (Node.getNodeType==Node.ELEMENT_NODE) 157 | RootNode=Node; 158 | elseif (Node.getNodeType==Node.PROCESSING_INSTRUCTION_NODE) 159 | data = strtrim(char(Node.getData)); 160 | target = strtrim(char(Node.getTarget)); 161 | GlobalProcInst = [target, ' ', data]; 162 | GlobalTextNodes{2} = GlobalProcInst; 163 | elseif (Node.getNodeType==Node.COMMENT_NODE) 164 | GlobalComment = strtrim(char(Node.getData)); 165 | GlobalTextNodes{3} = GlobalComment; 166 | % elseif (Node.getNodeType==Node.DOCUMENT_TYPE_NODE) 167 | % GlobalTextNodes{4} = GlobalDocType; 168 | end 169 | Node = Node.getNextSibling; 170 | end 171 | 172 | %% parse xml file through calls to recursive DOMnode2struct function 173 | if (Debug) % in debuging mode crashes are allowed 174 | [tree RootName] = DOMnode2struct(RootNode, DPref, 1); 175 | else % in normal mode crashes are not allowed 176 | try 177 | try 178 | [tree RootName] = DOMnode2struct(RootNode, DPref, 1); 179 | catch ME 180 | error('Unable to parse XML file %s: \n %s.',xmlfile, getReport(ME)); 181 | end 182 | catch %#ok catch for mablab versions prior to 7.5 183 | error('Unable to parse XML file %s.',xmlfile); 184 | end 185 | end 186 | 187 | %% If there were any Global Text nodes than return them 188 | if (~RootOnly) 189 | if (~isempty(GlobalProcInst) && DPref.ReadSpec) 190 | t.PROCESSING_INSTRUCTION = GlobalProcInst; 191 | end 192 | if (~isempty(GlobalComment) && DPref.ReadSpec) 193 | t.COMMENT = GlobalComment; 194 | end 195 | if (~isempty(GlobalDocType) && DPref.ReadSpec) 196 | t.DOCUMENT_TYPE = GlobalDocType; 197 | end 198 | t.(RootName) = tree; 199 | tree=t; 200 | end 201 | if (~isempty(GlobalTextNodes)) 202 | GlobalTextNodes{1} = RootName; 203 | RootName = GlobalTextNodes; 204 | end 205 | 206 | 207 | %% ======================================================================= 208 | % === DOMnode2struct Function =========================================== 209 | % ======================================================================= 210 | function [s TagName LeafNode] = DOMnode2struct(node, Pref, level) 211 | 212 | %% === Step 1: Get node name and check if it is a leaf node ============== 213 | [TagName LeafNode] = NodeName(node, Pref.KeepNS); 214 | s = []; % initialize output structure 215 | 216 | %% === Step 2: Process Leaf Nodes (nodes with no children) =============== 217 | if (LeafNode) 218 | if (LeafNode>1 && ~Pref.ReadSpec), LeafNode=-1; end % tags only so ignore special nodes 219 | if (LeafNode>0) % supported leaf node types 220 | try 221 | try % use try-catch: errors here are often due to VERY large fields (like images) that overflow java memory 222 | s = char(node.getData); 223 | if (isempty(s)), s = ' '; end % make it a string 224 | % for some reason current xmlread 'creates' a lot of empty text 225 | % fields with first chatacter=10 - those will be deleted. 226 | if (~Pref.PreserveSpace || s(1)==10) 227 | if (isspace(s(1)) || isspace(s(end))), s = strtrim(s); end % trim speces is any 228 | end 229 | if (LeafNode==1), s=str2var(s, Pref.Str2Num, 0); end % convert to number(s) if needed 230 | catch ME % catch for mablab versions 7.5 and higher 231 | warning('xml_io_tools:read:LeafRead', ... 232 | 'This leaf node could not be read and was ignored. '); 233 | getReport(ME) 234 | end 235 | catch %#ok catch for mablab versions prior to 7.5 236 | warning('xml_io_tools:read:LeafRead', ... 237 | 'This leaf node could not be read and was ignored. '); 238 | end 239 | end 240 | if (LeafNode==3) % ProcessingInstructions need special treatment 241 | target = strtrim(char(node.getTarget)); 242 | s = [target, ' ', s]; 243 | end 244 | return % We are done the rest of the function deals with nodes with children 245 | end 246 | if (level>Pref.NumLevels+1), return; end % if Pref.NumLevels is reached than we are done 247 | 248 | %% === Step 3: Process nodes with children =============================== 249 | if (node.hasChildNodes) % children present 250 | Child = node.getChildNodes; % create array of children nodes 251 | nChild = Child.getLength; % number of children 252 | 253 | % --- pass 1: how many children with each name ----------------------- 254 | f = []; 255 | for iChild = 1:nChild % read in each child 256 | [cname cLeaf] = NodeName(Child.item(iChild-1), Pref.KeepNS); 257 | if (cLeaf<0), continue; end % unsupported leaf node types 258 | if (~isfield(f,cname)), 259 | f.(cname)=0; % initialize first time I see this name 260 | end 261 | f.(cname) = f.(cname)+1; % add to the counter 262 | end % end for iChild 263 | % text_nodes become CONTENT & for some reason current xmlread 'creates' a 264 | % lot of empty text fields so f.CONTENT value should not be trusted 265 | if (isfield(f,'CONTENT') && f.CONTENT>2), f.CONTENT=2; end 266 | 267 | % --- pass 2: store all the children as struct of cell arrays ---------- 268 | for iChild = 1:nChild % read in each child 269 | [c cname cLeaf] = DOMnode2struct(Child.item(iChild-1), Pref, level+1); 270 | if (cLeaf && isempty(c)) % if empty leaf node than skip 271 | continue; % usually empty text node or one of unhandled node types 272 | elseif (nChild==1 && cLeaf==1) 273 | s=c; % shortcut for a common case 274 | else % if normal node 275 | if (level>Pref.NumLevels), continue; end 276 | n = f.(cname); % how many of them in the array so far? 277 | if (~isfield(s,cname)) % encountered this name for the first time 278 | if (n==1) % if there will be only one of them ... 279 | s.(cname) = c; % than save it in format it came in 280 | else % if there will be many of them ... 281 | s.(cname) = cell(1,n); 282 | s.(cname){1} = c; % than save as cell array 283 | end 284 | f.(cname) = 1; % initialize the counter 285 | else % already have seen this name 286 | s.(cname){n+1} = c; % add to the array 287 | f.(cname) = n+1; % add to the array counter 288 | end 289 | end 290 | end % for iChild 291 | end % end if (node.hasChildNodes) 292 | 293 | %% === Step 4: Post-process struct's created for nodes with children ===== 294 | if (isstruct(s)) 295 | fields = fieldnames(s); 296 | nField = length(fields); 297 | 298 | % Detect structure that looks like Html table and store it in cell Matrix 299 | if (nField==1 && strcmpi(fields{1},Pref.TableName{1})) 300 | tr = s.(Pref.TableName{1}); 301 | fields2 = fieldnames(tr{1}); 302 | if (length(fields2)==1 && strcmpi(fields2{1},Pref.TableName{2})) 303 | % This seems to be a special structure such that for 304 | % Pref.TableName = {'tr','td'} 's' corresponds to 305 | % M11 M12 306 | % M12 M22 307 | % Recognize it as encoding for 2D struct 308 | nr = length(tr); 309 | for r = 1:nr 310 | row = tr{r}.(Pref.TableName{2}); 311 | Table(r,1:length(row)) = row; %#ok 312 | end 313 | s = Table; 314 | end 315 | end 316 | 317 | % --- Post-processing: convert 'struct of cell-arrays' to 'array of structs' 318 | % Example: let say s has 3 fields s.a, s.b & s.c and each field is an 319 | % cell-array with more than one cell-element and all 3 have the same length. 320 | % Then change it to array of structs, each with single cell. 321 | % This way element s.a{1} will be now accessed through s(1).a 322 | vec = zeros(size(fields)); 323 | for i=1:nField, vec(i) = f.(fields{i}); end 324 | if (numel(vec)>1 && vec(1)>1 && var(vec)==0) % convert from struct of 325 | s = cell2struct(struct2cell(s), fields, 1); % arrays to array of struct 326 | end % if anyone knows better way to do above conversion please let me know. 327 | 328 | end 329 | 330 | %% === Step 5: Process nodes with attributes ============================= 331 | if (node.hasAttributes && Pref.ReadAttr) 332 | if (~isstruct(s)), % make into struct if is not already 333 | ss.CONTENT=s; 334 | s=ss; 335 | end 336 | Attr = node.getAttributes; % list of all attributes 337 | for iAttr = 1:Attr.getLength % for each attribute 338 | name = char(Attr.item(iAttr-1).getName); % attribute name 339 | name = str2varName(name, Pref.KeepNS); % fix name if needed 340 | value = char(Attr.item(iAttr-1).getValue); % attribute value 341 | value = str2var(value, Pref.Str2Num, 1); % convert to number if possible 342 | s.ATTRIBUTE.(name) = value; % save again 343 | end % end iAttr loop 344 | end % done with attributes 345 | if (~isstruct(s)), return; end %The rest of the code deals with struct's 346 | 347 | %% === Post-processing: fields of "s" 348 | % convert 'cell-array of structs' to 'arrays of structs' 349 | fields = fieldnames(s); % get field names 350 | nField = length(fields); 351 | for iItem=1:length(s) % for each struct in the array - usually one 352 | for iField=1:length(fields) 353 | field = fields{iField}; % get field name 354 | % if this is an 'item' field and user want to leave those as cells 355 | % than skip this one 356 | if (strcmpi(field, Pref.ItemName) && Pref.CellItem), continue; end 357 | x = s(iItem).(field); 358 | if (iscell(x) && all(cellfun(@isstruct,x(:))) && numel(x)>1) % it's cell-array of structs 359 | % numel(x)>1 check is to keep 1 cell-arrays created when Pref.CellItem=1 360 | try % this operation fails sometimes 361 | % example: change s(1).a{1}.b='jack'; s(1).a{2}.b='john'; to 362 | % more convinient s(1).a(1).b='jack'; s(1).a(2).b='john'; 363 | s(iItem).(field) = [x{:}]'; %#ok % converted to arrays of structs 364 | catch %#ok 365 | % above operation will fail if s(1).a{1} and s(1).a{2} have 366 | % different fields. If desired, function forceCell2Struct can force 367 | % them to the same field structure by adding empty fields. 368 | if (Pref.NoCells) 369 | s(iItem).(field) = forceCell2Struct(x); %#ok 370 | end 371 | end % end catch 372 | end 373 | end 374 | end 375 | 376 | %% === Step 4: Post-process struct's created for nodes with children ===== 377 | 378 | % --- Post-processing: remove special 'item' tags --------------------- 379 | % many xml writes (including xml_write) use a special keyword to mark 380 | % arrays of nodes (see xml_write for examples). The code below converts 381 | % s.item to s.CONTENT 382 | ItemContent = false; 383 | if (isfield(s,Pref.ItemName)) 384 | s.CONTENT = s.(Pref.ItemName); 385 | s = rmfield(s,Pref.ItemName); 386 | ItemContent = Pref.CellItem; % if CellItem than keep s.CONTENT as cells 387 | end 388 | 389 | % --- Post-processing: clean up CONTENT tags --------------------- 390 | % if s.CONTENT is a cell-array with empty elements at the end than trim 391 | % the length of this cell-array. Also if s.CONTENT is the only field than 392 | % remove .CONTENT part and store it as s. 393 | if (isfield(s,'CONTENT')) 394 | if (iscell(s.CONTENT) && isvector(s.CONTENT)) 395 | x = s.CONTENT; 396 | for i=numel(x):-1:1, if ~isempty(x{i}), break; end; end 397 | if (i==1 && ~ItemContent) 398 | s.CONTENT = x{1}; % delete cell structure 399 | else 400 | s.CONTENT = x(1:i); % delete empty cells 401 | end 402 | end 403 | if (nField==1) 404 | if (ItemContent) 405 | ss = s.CONTENT; % only child: remove a level but ensure output is a cell-array 406 | s=[]; s{1}=ss; 407 | else 408 | s = s.CONTENT; % only child: remove a level 409 | end 410 | end 411 | end 412 | 413 | 414 | 415 | %% ======================================================================= 416 | % === forceCell2Struct Function ========================================= 417 | % ======================================================================= 418 | function s = forceCell2Struct(x) 419 | % Convert cell-array of structs, where not all of structs have the same 420 | % fields, to a single array of structs 421 | 422 | %% Convert 1D cell array of structs to 2D cell array, where each row 423 | % represents item in original array and each column corresponds to a unique 424 | % field name. Array "AllFields" store fieldnames for each column 425 | AllFields = fieldnames(x{1}); % get field names of the first struct 426 | CellMat = cell(length(x), length(AllFields)); 427 | for iItem=1:length(x) 428 | fields = fieldnames(x{iItem}); % get field names of the next struct 429 | for iField=1:length(fields) % inspect all fieldnames and find those 430 | field = fields{iField}; % get field name 431 | col = find(strcmp(field,AllFields),1); 432 | if isempty(col) % no column for such fieldname yet 433 | AllFields = [AllFields; field]; %#ok 434 | col = length(AllFields); % create a new column for it 435 | end 436 | CellMat{iItem,col} = x{iItem}.(field); % store rearanged data 437 | end 438 | end 439 | %% Convert 2D cell array to array of structs 440 | s = cell2struct(CellMat, AllFields, 2); 441 | 442 | %% ======================================================================= 443 | % === str2var Function ================================================== 444 | % ======================================================================= 445 | function val=str2var(str, option, attribute) 446 | % Can this string 'str' be converted to a number? if so than do it. 447 | val = str; 448 | len = numel(str); 449 | if (len==0 || option==0), return; end % Str2Num="never" of empty string -> do not do enything 450 | if (len>10000 && option==1), return; end % Str2Num="smart" and string is very long -> probably base64 encoded binary 451 | digits = '(Inf)|(NaN)|(pi)|[\t\n\d\+\-\*\.ei EI\[\]\;\,]'; 452 | s = regexprep(str, digits, ''); % remove all the digits and other allowed characters 453 | if (~all(~isempty(s))) % if nothing left than this is probably a number 454 | if (~isempty(strfind(str, ' '))), option=2; end %if str has white-spaces assume by default that it is not a date string 455 | if (~isempty(strfind(str, '['))), option=2; end % same with brackets 456 | str(strfind(str, '\n')) = ';';% parse data tables into 2D arrays, if any 457 | if (option==1) % the 'smart' option 458 | try % try to convert to a date, like 2007-12-05 459 | datenum(str); % if successful than leave it as string 460 | catch %#ok % if this is not a date than ... 461 | option=2; % ... try converting to a number 462 | end 463 | end 464 | if (option==2) 465 | if (attribute) 466 | num = str2double(str); % try converting to a single number using sscanf function 467 | if isnan(num), return; end % So, it wasn't really a number after all 468 | else 469 | num = str2num(str); %#ok % try converting to a single number or array using eval function 470 | end 471 | if(isnumeric(num) && numel(num)>0), val=num; end % if convertion to a single was succesful than save 472 | end 473 | elseif ((str(1)=='[' && str(end)==']') || (str(1)=='{' && str(end)=='}')) % this looks like a (cell) array encoded as a string 474 | try 475 | val = eval(str); 476 | catch %#ok 477 | val = str; 478 | end 479 | elseif (~attribute) % see if it is a boolean array with no [] brackets 480 | str1 = lower(str); 481 | str1 = strrep(str1, 'false', '0'); 482 | str1 = strrep(str1, 'true' , '1'); 483 | s = regexprep(str1, '[01 \;\,]', ''); % remove all 0/1, spaces, commas and semicolons 484 | if (~all(~isempty(s))) % if nothing left than this is probably a boolean array 485 | num = str2num(str1); %#ok 486 | if(isnumeric(num) && numel(num)>0), val = (num>0); end % if convertion was succesful than save as logical 487 | end 488 | end 489 | 490 | 491 | %% ======================================================================= 492 | % === str2varName Function ============================================== 493 | % ======================================================================= 494 | function str = str2varName(str, KeepNS) 495 | % convert a sting to a valid matlab variable name 496 | if(KeepNS) 497 | str = regexprep(str,':','_COLON_', 'once', 'ignorecase'); 498 | else 499 | k = strfind(str,':'); 500 | if (~isempty(k)) 501 | str = str(k+1:end); 502 | end 503 | end 504 | str = regexprep(str,'-','_DASH_' ,'once', 'ignorecase'); 505 | if (~isvarname(str)) && (~iskeyword(str)) 506 | str = genvarname(str); 507 | end 508 | 509 | %% ======================================================================= 510 | % === NodeName Function ================================================= 511 | % ======================================================================= 512 | function [Name LeafNode] = NodeName(node, KeepNS) 513 | % get node name and make sure it is a valid variable name in Matlab. 514 | % also get node type: 515 | % LeafNode=0 - normal element node, 516 | % LeafNode=1 - text node 517 | % LeafNode=2 - supported non-text leaf node, 518 | % LeafNode=3 - supported processing instructions leaf node, 519 | % LeafNode=-1 - unsupported non-text leaf node 520 | switch (node.getNodeType) 521 | case node.ELEMENT_NODE 522 | Name = char(node.getNodeName);% capture name of the node 523 | Name = str2varName(Name, KeepNS); % if Name is not a good variable name - fix it 524 | LeafNode = 0; 525 | case node.TEXT_NODE 526 | Name = 'CONTENT'; 527 | LeafNode = 1; 528 | case node.COMMENT_NODE 529 | Name = 'COMMENT'; 530 | LeafNode = 2; 531 | case node.CDATA_SECTION_NODE 532 | Name = 'CDATA_SECTION'; 533 | LeafNode = 2; 534 | case node.DOCUMENT_TYPE_NODE 535 | Name = 'DOCUMENT_TYPE'; 536 | LeafNode = 2; 537 | case node.PROCESSING_INSTRUCTION_NODE 538 | Name = 'PROCESSING_INSTRUCTION'; 539 | LeafNode = 3; 540 | otherwise 541 | NodeType = {'ELEMENT','ATTRIBUTE','TEXT','CDATA_SECTION', ... 542 | 'ENTITY_REFERENCE', 'ENTITY', 'PROCESSING_INSTRUCTION', 'COMMENT',... 543 | 'DOCUMENT', 'DOCUMENT_TYPE', 'DOCUMENT_FRAGMENT', 'NOTATION'}; 544 | Name = char(node.getNodeName);% capture name of the node 545 | warning('xml_io_tools:read:unkNode', ... 546 | 'Unknown node type encountered: %s_NODE (%s)', NodeType{node.getNodeType}, Name); 547 | LeafNode = -1; 548 | end 549 | 550 | 551 | -------------------------------------------------------------------------------- /xml_io_tools/code/xml_tutorial_script.m: -------------------------------------------------------------------------------- 1 | %% Tutorial for xml_io_tools Package 2 | % *By Jarek Tuszynski* 3 | % 4 | % Package xml_io_tools can read XML files into MATLAB struct and writes 5 | % MATLAB data types to XML files with help of simple interface to 6 | % MATLAB's xmlwrite and xmlread functions. 7 | % 8 | % Two function to simplify reading and writing XML files from MATLAB: 9 | % 10 | % * Function xml_read first calls MATLAB's xmlread function and than 11 | % converts its output ('Document Object Model' tree of Java objects) 12 | % to tree of MATLAB struct's. The output is in the format of nested 13 | % structs and cells. In the output data structure field names are based on 14 | % XML tags. 15 | % 16 | % * Function xml_write first convert input tree of MATLAB structs and cells 17 | % and other types to tree of 'Document Object Model' nodes, and then writes 18 | % resulting object to XML file using MATLAB's xmlwrite function. . 19 | % 20 | %% This package can: 21 | % * Read most XML files, created inside and outside of MATLAB environment, 22 | % and convert them to MATLAB data structures. 23 | % * Write any MATLAB's struct tree to XML file 24 | % * Handle XML attributes and special XML nodes like comments, processing 25 | % instructions and CDATA sections 26 | % * Supports base64 encoding and decoding to allow handling embeded binary 27 | % data 28 | % * Be studied, modified, customized, rewritten and used in other packages 29 | % without any limitations. All code is included and documented. Software 30 | % is distributed under BSD Licence (included). 31 | % 32 | %% This package does not: 33 | % * Guarantee to recover the same Matlab objects that were saved. If you 34 | % need to be able to recover carbon copy of the structure that was saved 35 | % than you will have to use one of the packages that uses special set of 36 | % tags saved as xml attributes that help to guide the parsing of XML code. 37 | % This package does not use those tags. 38 | % * Guarantee to work with older versions of MATLAB. Functions do not work 39 | % with versions of MATLAB prior to 7.1 (26-Jul-2005). 40 | % 41 | %% Change History 42 | % * 2006-11-06 - original version 43 | % * 2006-11-26 - corrected xml_write to handle writing Matlab's column 44 | % arrays to xml files. Bug discovered and diagnosed by Kalyan Dutta. 45 | % * 2006-11-28 - made changes to handle special node types like: 46 | % COMMENTS and CDATA sections 47 | % * 2007-03-12 - Writing CDATA sections still did not worked. The problem 48 | % was diagnosed and fixed by Alberto Amaro. The fix involved rewriting 49 | % xmlwrite to use Apache Xerces java files directly instead of MATLAB's 50 | % XMLUtils java class. 51 | % * 2007-06-21 - Fixed problem reported by Anna Kelbert in Reviews about 52 | % not writing attributes of ROOT node. Also: added support for Processing 53 | % Instructions, added support for global text nodes: Processing 54 | % Instructions and comments, allowed writing tag names with special 55 | % characters 56 | % * 2007-07-20 - Added tutorial script file. Extended support for global 57 | % text nodes. Added more Preference fields. 58 | % * 2008-01-23 - Fixed problem reported by Anna Krewet of converting dates 59 | % in format '2007-01-01' to numbers. Improved and added warning messages. 60 | % Added detection of old Matlab versions incompatible with the library. 61 | % Expanded documentation. 62 | % * 2008-06-23 - Fixed problem with writing 1D array reported by Mark Neil. 63 | % Extended xml_read's Pref.Num2Str to 3 settings (never, smart and always) 64 | % for better control. Added parameter Pref.KeepNS for keeping or ignoring 65 | % namespace data when reading. Fixed a bug related to writing 2D cell 66 | % arrays brought up by Andrej's Mosat review. 67 | % * 2008-09-11 - Resubmitting last upload - zip file is still old 68 | % * 2009-02-26 - Small changes. More error handling. More robust in case of 69 | % large binary objects. Added support for Base64 encoding/decoding of 70 | % binary objects (using functions by Peter J. Acklam). 71 | % * 2009-06-26 - changes to xml_read: added CellItem parameter to allow 72 | % better control of reading files with 'item' notation (see comment by 73 | % Shlomi); changed try-catch statements so xml_read would work for mablab 74 | % versions prior to 7.5 (see Thomas Pilutti comment) 75 | % * 2009-12-03 - added PreserveSpace parameter for contolling empty string 76 | % handling as suggested by Sebastiaan. Fix suggested by Michael Murphy. 77 | % Fixed number recognition code as suggested by Yuan Ren. 78 | % * 2010-05-04 - implemented fixes suggested by Dylan Reynolds from Airbus. 79 | % * 2010-07-28 - implemented support for 2D arrays of cells and structs 80 | % suggested by Rodney Behn from MIT Lincoln Laboratory. Also attempted 81 | % large scale cleanup of xml_write function 82 | % * 2010-08-18 - minor extension to allow better handling of logical 83 | % scalars and arrays and function handles suggested by Andreas Richter 84 | % and others 85 | % * 2010-09-20 - allow reading and writing of sparse matrices. Improve 86 | % reading of 1D boolean arrays. 87 | % * 2010-11-05 - Fix problem with empty cells reported by Richard Cotton; 88 | % fixed issues with reading boolean arrays reported by Zohar Bar-Yehuda; 89 | % Improved speed of base64 coding and decoding by switching to java based 90 | % code. 91 | %% Licence 92 | % The package is distributed under BSD License 93 | format compact; % viewing preference 94 | clear variables; 95 | type('license.txt') 96 | 97 | %% Write XML file based on a Struct using "xml_write" 98 | % Any MATLAB data struct can be saved to XML file. 99 | MyTree=[]; 100 | MyTree.MyNumber = 13; 101 | MyTree.MyString = 'Hello World'; 102 | xml_write('test.xml', MyTree); 103 | type('test.xml') 104 | 105 | %% Read XML file producing a Struct using "xml_read" 106 | [tree treeName] = xml_read ('test.xml'); 107 | disp([treeName{1} ' =']) 108 | gen_object_display(tree) 109 | 110 | %% "Pref.XmlEngine" flag in "xml_write" 111 | % Occasionaly some operations are performed better by Apache Xerces XML 112 | % engine than default xmlread function. That is why xml_write provide an 113 | % option for choosing the underlaying xml engine. Code below performs the 114 | % same operation as the previous section but using Apache Xerces XML engine. 115 | % Notice that in this case name of root element 116 | % was passed as variable and not extracted from the variable name. 117 | Pref=[]; Pref.XmlEngine = 'Xerces'; % use Xerces xml generator directly 118 | xml_write('test.xml', MyTree, 'TreeOfMine', Pref); 119 | type('test.xml') 120 | 121 | %% Writing Struct with different type MATLAB arrays 122 | MyTree=[]; 123 | MyTree.Empty = []; % Empty variable 124 | MyTree.Num_1x1 = 13; % simple scalar 125 | MyTree.Vec_1x3 = [1 2 3]; % horizontal vector 126 | MyTree.Vec_4x1 = [1; 2; 3; 4]; % vertical vector 127 | MyTree.Mat_2x2 = [1, 2; 3, 4]; % 2D matrix 128 | MyTree.Cube_3D = reshape(1:8,[2 2 2]); % 3D array 129 | MyTree.String1 = '[2003 10 30]'; % number string with [] brackets 130 | MyTree.String2 = ' 2003 10 30 '; % number string without [] brackets 131 | MyTree.Logical_1x1 = false; % single logical 132 | MyTree.Logical_2x2 = [false, true; true, false]; % 2D matrix of logicals 133 | MyTree.Logical_Str = 'False False True True'; 134 | MyTree.Int_2x2 = uint8([1 2;3 4]); % 2D matrix of uint8 integers 135 | MyTree.Complex_1x1 = complex(1, 7); % complex scalar 136 | MyTree.Complex_2x2 = complex([1 2;3 4],[2 2;7 7]); % 2D matrix of complex numbers 137 | MyTree.Sparse_9x9 = sparse(1:9,1:9,1); % sparse 9x9 matrix 138 | MyTree.Function = @sum; % function handle 139 | xml_write('test.xml', MyTree); 140 | type('test.xml') 141 | 142 | %% Read Struct with MATLAB arrays 143 | % Notice that 'Cube_3D' did not preserve original dimentions 144 | [tree treeName] = xml_read ('test.xml'); 145 | disp([treeName{1} ' =']) 146 | gen_object_display(tree) 147 | 148 | %% "Pref.StructItem" flag in "xml_write" (controls 1D arrays of structs) 149 | % *Create a simple structure with 1D array of struct's* 150 | MyTree = []; 151 | MyTree.a(1).b = 'jack'; 152 | MyTree.a(2).b = 'john'; 153 | gen_object_display(MyTree) 154 | %% 155 | % *Write XML with "StructItem = true" (default). Notice single 'a' 156 | % section and multiple 'item' sub-sections. Those subsections are used 157 | % to store array elements* 158 | wPref.StructItem = true; 159 | xml_write('test.xml', MyTree, 'MyTree',wPref); 160 | type('test.xml') 161 | fprintf('\nxml_read output:\n') 162 | gen_object_display(xml_read ('test.xml')) 163 | %% 164 | % *Write XML with "StructItem = false". Notice multiple 'a' sections* 165 | wPref.StructItem = false; 166 | xml_write('test.xml', MyTree, 'MyTree',wPref); 167 | type('test.xml') 168 | fprintf('\nxml_read output:\n') 169 | gen_object_display(xml_read ('test.xml')) 170 | %% 171 | % *Notice that xml_read function produced the same struct when reading both files* 172 | %% 173 | % *Potential problems with "StructItem = true":* 174 | wPref.StructItem = true; 175 | MyTree1 = []; MyTree1.a.b = 'jack'; 176 | MyTree2 = []; MyTree2.a(1).b = 'jack'; 177 | MyTree3 = []; MyTree3.a(2).b = 'jack'; 178 | xml_write('test.xml', MyTree1, [], wPref); type('test.xml'); 179 | xml_write('test.xml', MyTree2, [], wPref); type('test.xml'); 180 | xml_write('test.xml', MyTree3, [], wPref); type('test.xml'); 181 | %% 182 | % *Notice that MyTree1 and MyTree2 produce identical files with no 'items', 183 | % while MyTree2 and MyTree3 produce very different file structures. It was 184 | % pointed out to me that files produced from MyTree2 and MyTree3 can not 185 | % belong to the same schema, which can be a problem. The solution is to use 186 | % cells.* 187 | wPref.CellItem = true; 188 | wPref.NoCells = true; 189 | MyTree2 = []; MyTree2.a{1}.b = 'jack'; 190 | MyTree3 = []; MyTree3.a{2}.b = 'jack'; 191 | xml_write('test.xml', MyTree2, [], wPref); type('test.xml'); 192 | xml_write('test.xml', MyTree3, [], wPref); type('test.xml'); 193 | 194 | 195 | %% "Pref.CellItem" flag in "xml_write" (controls 1D arrays of cells) 196 | % *Create a simple structure with cell arrays* 197 | MyTree = []; 198 | MyTree.a = {'jack', 'john'}; 199 | disp(MyTree) 200 | %% 201 | % *Write XML with "CellItem = true" (default). Notice single 'a' 202 | % section and multiple 'item' sections* 203 | Pref=[]; Pref.CellItem = true; 204 | xml_write('test.xml', MyTree, 'MyTree',Pref); 205 | type('test.xml') 206 | fprintf('\nxml_read output:\n'); 207 | disp(xml_read ('test.xml')) 208 | %% 209 | % *Write XML with "CellItem = false". Notice multiple 'a' sections* 210 | Pref=[]; Pref.CellItem = false; 211 | xml_write('test.xml', MyTree, 'MyTree',Pref); 212 | type('test.xml') 213 | fprintf('\nxml_read output:\n'); 214 | disp(xml_read ('test.xml')) 215 | %% 216 | % *Notice that xml_read function produced the same struct when reading both files* 217 | 218 | %% "Pref.NoCells" flag in "xml_read" 219 | % *Create a cell/struct mixture object* 220 | MyTree = []; 221 | MyTree.a{1}.b = 'jack'; 222 | MyTree.a{2}.b = []; 223 | MyTree.a{2}.c = 'john'; 224 | gen_object_display(MyTree); 225 | %% 226 | % *Save it to xml file* 227 | Pref=[]; Pref.CellItem = false; 228 | xml_write('test.xml', MyTree, 'MyTree',Pref); 229 | type('test.xml') 230 | %% 231 | % *Read above file with "Pref.NoCells=true" (default) - output is quite different then input* 232 | % By default program is trying to convert everything to struct's and arrays 233 | % of structs. In case arrays of structs all the structs in array need to have the 234 | % same fields, and if they are not than MATLAB creates empty fields. 235 | Pref=[]; Pref.NoCells=true; 236 | gen_object_display(xml_read('test.xml', Pref)) 237 | %% 238 | % *Read above file with "Pref.NoCells=false" - now input and output are the same* 239 | % Cell arrays of structs allow structs in array to have different fields. 240 | Pref=[]; Pref.NoCells=false; 241 | gen_object_display(xml_read('test.xml', Pref)) 242 | 243 | %% "Pref.ItemName" flag in "xml_write" (customize 1D arrays of structs and cells) 244 | % *Create a cell/struct mixture object* 245 | MyTree = []; 246 | MyTree.a{1}.b = 'jack'; 247 | MyTree.a{2}.c = 'john'; 248 | gen_object_display(MyTree); 249 | %% 250 | % *Save it to xml file, using 'item' notation but with different name* 251 | Pref=[]; 252 | Pref.CellItem = true; 253 | Pref.ItemName = 'MyItem'; 254 | xml_write('test.xml', MyTree, 'MyTree',Pref); 255 | type('test.xml') 256 | 257 | %% "Pref.ItemName" flag in "xml_read" 258 | % *Read above file with default settings ("Pref.ItemName = 'item'")* 259 | % The results do not match the original structure 260 | Pref=[]; Pref.NoCells = false; 261 | gen_object_display(xml_read('test.xml', Pref)) 262 | %% 263 | % *Read above file with "Pref.ItemName = 'MyItem'" - now saved and read 264 | % MATLAB structures are the same* 265 | Pref=[]; 266 | Pref.ItemName = 'MyItem'; 267 | Pref.NoCells = false; 268 | gen_object_display(xml_read('test.xml', Pref)) 269 | 270 | %% "Pref.CellItem" flag in "xml_read" 271 | % "Pref.ItemName" is used to create xml files with clearly marked arrays 272 | % "Pref.CellItem" flag in "xml_read" ensures that they are always read as 273 | % arrays by forcing output to stay in cell format. In cell format s{1} is 274 | % different than s, while s(1) is indistinguishable from s. 275 | %% 276 | % *Create a test file* 277 | MyTree = []; 278 | MyTree.a1{1}.b = 'jack'; % a1 - single struct 279 | MyTree.a2{1}.b = 'jack'; % a2 - cell array of structs with the same fields 280 | MyTree.a2{2}.b = 'john'; 281 | MyTree.a3{1}.b = 'jack'; % a3 - cell array of structs with the different fields 282 | MyTree.a3{2}.c = 'john'; 283 | Pref=[]; 284 | Pref.CellItem = true; 285 | Pref.Debug = true; 286 | xml_write('test.xml', MyTree, 'MyTree',Pref); 287 | type('test.xml') 288 | %% 289 | % *Read above file with "Pref.CellItem = true" (default)* 290 | % All outputs are in cell format 291 | Pref=[]; 292 | Pref.NoCells = false; % allow cell output 293 | Pref.CellItem = true; % keep 'item' arrays as cells 294 | gen_object_display(xml_read('test.xml', Pref)) 295 | %% 296 | % *Read above file with "Pref.CellItem = false"* 297 | % Outputs format is determined by content 298 | Pref=[]; 299 | Pref.NoCells = false; % allow cell output 300 | Pref.CellItem = false; % allow 'item' arrays to beheave like other fields 301 | gen_object_display(xml_read('test.xml', Pref)) 302 | %% 303 | % *Read above file with "Pref.CellItem = false" and "Pref.NoCells = true"* 304 | % All outputs are in struct format 305 | Pref=[]; 306 | Pref.NoCells = true; % don't allow cell output 307 | Pref.CellItem = false; % allow 'item' arrays to beheave like other fields 308 | gen_object_display(xml_read('test.xml', Pref)) 309 | 310 | %% "Pref.CellTable" flag in "xml_write" (controls 2D arrays of cells) 311 | % *Create a structure with 2D arrays of cells* 312 | MyTree = []; 313 | MyTree.M = {[1,2;3,4], 'M12'; struct('a','jack'), {11, 'N12'; 21, 'N22'}}; 314 | gen_object_display(MyTree) 315 | %% 316 | % *Write XML with "CellTable = 'Html" (default). This option mimics use of 317 | % HTML "tr" and "td" tags to encode 2D tables. Tag names can 318 | % be changed using TableName parameter (see below)* 319 | wPref = []; 320 | wPref.CellTable = 'Html'; 321 | xml_write('test.xml', MyTree, 'MyTree',wPref); 322 | type('test.xml') 323 | fprintf('\nxml_read output:\n') 324 | rPref=[]; rPref.NoCells=false; 325 | gen_object_display(xml_read('test.xml', rPref)) 326 | %% 327 | % *Write XML with "CellTable = 'Vector'".* 328 | % Converts 2D arrays to 1D array and item or regular notation. This option 329 | % is mostly provided for backward compatibility since this was the 330 | % behavior in prior verions of the code 331 | wPref = []; 332 | wPref.CellTable = 'Vector'; 333 | xml_write('test.xml', MyTree, 'MyTree',wPref); 334 | type('test.xml') 335 | fprintf('\nxml_read output:\n') 336 | rPref=[]; rPref.NoCells=false; 337 | gen_object_display(xml_read('test.xml', rPref)) 338 | %% 339 | % *Create a simpler structure without struct's* 340 | MyTree = []; 341 | MyTree.M = {[1,2;3,4], 'M12'; 'M21', {11, 'N12'; 21, 'N22'}}; 342 | gen_object_display(MyTree) 343 | %% 344 | % *Write XML with "CellTable = 'Matlab". This option encodes tables 345 | % consisting of numbers, strings and other cell arrays as MATLAB command 346 | % string. Unlike 'Html' option it does not work if one of the cells is 347 | % a struct* 348 | wPref = []; 349 | wPref.CellTable = 'Matlab'; 350 | xml_write('test.xml', MyTree, 'MyTree',wPref); 351 | type('test.xml') 352 | fprintf('\nxml_read output:\n') 353 | rPref=[]; rPref.NoCells=false; 354 | gen_object_display(xml_read('test.xml', rPref)) 355 | 356 | %% Write 2D cell array in HTML format 357 | MyTree = []; 358 | MyTree.table.ATTRIBUTE.border=1; 359 | MyTree.table.CONTENT = {'Apples', '44%'; 'Bannanas', '23%'; 'Oranges', '13%'; 'Other', '10%'}; 360 | xml_write('html/test.html', MyTree); 361 | type('html/test.html') 362 | %% 363 | % Click on to opened this file with a web brouwser 364 | 365 | %% "Pref.StructTable" flag in "xml_write" (controls 2D arrays of structs) 366 | % *Create a simple structure with arrays of struct's* 367 | MyTree = []; 368 | MyTree.a(1,1).b = 'jack'; 369 | MyTree.a(1,2).b = 'john'; 370 | MyTree.a(2,1).b = 'jim'; 371 | MyTree.a(2,2).b = 'jill'; 372 | gen_object_display(MyTree) 373 | %% 374 | % *Write XML with "StructTable = 'Html" (default). This option mimics use of 375 | % HTML "tr" and "td" tags to encode 2D tables. Tag names can 376 | % be changed using TableName parameter (see below)* 377 | wPref = []; 378 | wPref.StructTable = 'Html'; 379 | xml_write('test.xml', MyTree, 'MyTree',wPref); 380 | type('test.xml') 381 | fprintf('\nxml_read output:\n') 382 | gen_object_display(xml_read ('test.xml')) 383 | %% 384 | % *Write XML with "CellTable = 'Vector'".* 385 | % Converts 2D arrays to 1D array and item or regular notation. This option 386 | % is mostly provided for backward compatibility since this was the 387 | % behavior in prior verions of the code 388 | wPref = []; 389 | wPref.StructTable = 'Vector'; 390 | xml_write('test.xml', MyTree, 'MyTree',wPref); 391 | type('test.xml') 392 | fprintf('\nxml_read output:\n') 393 | gen_object_display(xml_read ('test.xml')) 394 | 395 | %% "Pref.TableName" flag in "xml_write" (controls encoding tags used for 2D arrays) 396 | % *Create a cell object* 397 | MyTree = []; 398 | MyTree.M = {[1,2;3,4], 'M12'; 21, {11, 'N12'; 21, 'N22'}}; 399 | gen_object_display(MyTree); 400 | %% 401 | % *Save it to xml file, using 'Html' notation but with different names for 402 | % rows and cells* 403 | Pref=[]; Pref.TableName = {'row','cell'}; 404 | xml_write('test.xml', MyTree, 'MyTree',Pref); 405 | type('test.xml') 406 | 407 | %% "Pref.TableName" flag in "xml_read" 408 | % *Read above file with default settings ("Pref.TableName = {'tr','td'}")* 409 | % The results do not match the original structure 410 | Pref=[]; Pref.NoCells = false; 411 | gen_object_display(xml_read('test.xml', Pref)) 412 | %% 413 | % *Read above file with "Pref.TableName = {'row','cell'}" - now saved and read 414 | % MATLAB structures are the same* 415 | Pref=[]; 416 | Pref.TableName = {'row','cell'}; 417 | Pref.NoCells = false; 418 | gen_object_display(xml_read('test.xml', Pref)) 419 | 420 | %% "Pref.Str2Num" flag in xml_read (control conversion to numbers while reading) 421 | % *Create a cell/struct mixture object* 422 | MyTree = []; 423 | MyTree.str = 'sphere'; 424 | MyTree.num1 = 123; 425 | MyTree.num2 = '123'; 426 | MyTree.num3 = '[Inf,NaN]'; 427 | MyTree.calc = '1+2+3+4'; 428 | MyTree.func = 'sin(pi)/2'; 429 | MyTree.String1 = '[2003 10 30]'; 430 | MyTree.String2 = '2003 10 30'; % array resembling date 431 | MyTree.ISO8601 = '2003-10-30'; % date in ISO 8601 format 432 | MyTree.US_date = '2003/10/30'; % US style date format 433 | MyTree.complex = '2003i-10e-30'; % complex number resembling a date 434 | gen_object_display(MyTree); 435 | %% 436 | % *Save it to xml file* 437 | xml_write('test.xml', MyTree); 438 | type('test.xml') 439 | %% 440 | % *Read above file with default settings* 441 | % ("Pref.Str2Num = true" or "Pref.Str2Num = 'smart'"). Under this setting all 442 | % strings that look like numbers are converted to numbers, except for 443 | % strings that are recognized by MATLAB 'datenum' function as dates 444 | gen_object_display(xml_read('test.xml')) 445 | %% 446 | % *Note that all the fields of 'MyTree' can be converted to numbers (even 447 | % 'sphere') but by default the function is trying to 'judge' if a string 448 | % should be converted to a number or not* 449 | MyCell = {'sphere','1+2+3+4','sin(pi)/2','2003 10 30','2003-10-30','2003/10/30','2003i-10e-30'}; 450 | cellfun(@str2num, MyCell, 'UniformOutput', false) 451 | %% 452 | % *Read above file with "Pref.Str2Num = false" or "Pref.Str2Num = 'never'" 453 | % to keep all the fields in string format* 454 | Pref=[]; Pref.Str2Num = false; 455 | gen_object_display(xml_read('test.xml', Pref)) 456 | %% 457 | % *Read above file with "Pref.Str2Num = always" 458 | % to convert all strings that look like numbers to numbers* note the likelly 459 | % unintendet conversion of 'ISO8601' 460 | Pref=[]; Pref.Str2Num = 'always'; 461 | gen_object_display(xml_read('test.xml', Pref)) 462 | %% 463 | % *Notice that all three settings will produce the same output for "num1" and 464 | % "num2" and there is no way to reproduce the original "MyTree" structure.* 465 | 466 | %% "Pref.PreserveSpace" flag in xml_write (control handling of strings with leading/trailing spaces) 467 | % *Create a struct with strings* 468 | MyTree=[]; 469 | MyTree.Empty = ''; 470 | MyTree.OneSpace = ' '; 471 | MyTree.TwoSpaces = ' '; 472 | MyTree.String1 = ' Hello World '; 473 | %% 474 | % *Write XML with "PreserveSpace = false" (default).* 475 | Pref=[]; Pref.PreserveSpace = false; % (default setting) 476 | xml_write('test.xml', MyTree, [], Pref); 477 | type('test.xml') 478 | %% 479 | % *Write XML with "PreserveSpace = true".* 480 | Pref=[]; Pref.PreserveSpace = true; 481 | xml_write('test.xml', MyTree, [], Pref); 482 | type('test.xml') 483 | 484 | %% "Pref.PreserveSpace" flag in xml_read 485 | % *Read file while using "PreserveSpace = false" (default).* 486 | Pref=[]; Pref.PreserveSpace = false; % (default setting) 487 | gen_object_display(xml_read('test.xml',Pref)) 488 | %% 489 | % *Read file while using "PreserveSpace = true".* 490 | Pref=[]; Pref.PreserveSpace = true; 491 | gen_object_display(xml_read('test.xml',Pref)) 492 | 493 | 494 | %% Write XML files with ATTRIBUTEs 495 | % In order to add node attributes a special ATTRIBUTE field is used. 496 | % ATTRIBUTEs have to be of simple types like numbers or strings (not 497 | % struct or cells). Attributes are easy to attach to structs nodes like 498 | % MyTree below. 499 | MyTree=[]; 500 | MyTree.MyNumber = 13; 501 | MyTree.MyString = 'Hello World'; % simple case 502 | MyTree.ATTRIBUTE.Num = 2; 503 | xml_write('test.xml', MyTree); 504 | type('test.xml') 505 | 506 | %% 507 | % In case when one needs to attach attributes to nodes which are not 508 | % structs (for example strings, numbers or calls) then special CONTENT 509 | % field needs to be used to make the node a struct node. 510 | MyTree=[]; 511 | MyTree.MyNumber = 13; 512 | MyTree.MyString.CONTENT = 'Hello World'; % simple case 513 | MyTree.MyString.ATTRIBUTE.Num = 2; 514 | xml_write('test.xml', MyTree); 515 | type('test.xml') 516 | 517 | %% "Pref.Str2Num" flag in file with ATTRIBUTEs 518 | % *Create a cell/struct mixture object* 519 | MyTree = []; 520 | MyTree.X.ATTRIBUTE.str = 'sphere'; 521 | MyTree.X.ATTRIBUTE.num1 = 123; 522 | MyTree.X.ATTRIBUTE.num2 = '123'; 523 | MyTree.X.ATTRIBUTE.num3 = '[Inf,NaN]'; 524 | MyTree.X.ATTRIBUTE.calc = '1+2+3+4'; 525 | MyTree.X.ATTRIBUTE.func = 'sin(pi)/2'; 526 | MyTree.X.ATTRIBUTE.String1 = '[2003 10 30]'; 527 | MyTree.X.ATTRIBUTE.String2 = '2003 10 30'; % array resembling date 528 | MyTree.X.ATTRIBUTE.ISO8601 = '2003-10-30'; % date in ISO 8601 format 529 | MyTree.X.ATTRIBUTE.US_date = '2003/10/30'; % US style date format 530 | MyTree.X.ATTRIBUTE.complex = '2003i-10e-30'; % complex number resembling a date 531 | gen_object_display(MyTree); 532 | %% 533 | % *Save it to xml file* 534 | xml_write('test.xml', MyTree); 535 | type('test.xml') 536 | %% 537 | % *Read above file with default settings* 538 | % ("Pref.Str2Num = true" or "Pref.Str2Num = 'smart'"). Under this setting all 539 | % strings that look like numbers are converted to numbers, except for 540 | % strings that are recognized by MATLAB 'datenum' function as dates 541 | gen_object_display(xml_read('test.xml')) 542 | 543 | %% 544 | % *Read above file with "Pref.Str2Num = false" or "Pref.Str2Num = 'never'" 545 | % to keep all the fields in string format* 546 | Pref=[]; Pref.Str2Num = false; 547 | gen_object_display(xml_read('test.xml', Pref)) 548 | %% 549 | % *Read above file with "Pref.Str2Num = always" 550 | % to convert all strings that look like numbers to numbers* 551 | Pref=[]; Pref.Str2Num = 'always'; 552 | gen_object_display(xml_read('test.xml', Pref)) 553 | %% 554 | % *Notice that all three settings will produce the same output for "num1" and 555 | % "num2" and there is no way to reproduce the original "MyTree" structure.* 556 | 557 | 558 | %% Write XML files with COMMENTs 559 | % Insertion of Comments is done with help of special COMMENT field. 560 | % Note that MATLAB's xmlwrite is less readable due to lack of end-of-line 561 | % characters around comment section. 562 | MyTree=[]; 563 | MyTree.COMMENT = 'This is a comment'; 564 | MyTree.MyNumber = 13; 565 | MyTree.MyString.CONTENT = 'Hello World'; 566 | xml_write('test.xml', MyTree); 567 | type('test.xml') 568 | 569 | %% 570 | % *Same operation using Apache Xerces XML engine* 571 | % gives the same result 572 | Pref=[]; Pref.XmlEngine = 'Xerces'; % use Xerces xml generator directly 573 | xml_write('test.xml', MyTree, 'MyTree', Pref); 574 | type('test.xml') 575 | 576 | %% 577 | % *Comments in XML top level (method #1)* 578 | % This method uses cell array 579 | MyTree=[]; 580 | MyTree.MyNumber = 13; 581 | MyTree.MyString = 'Hello World'; 582 | xml_write('test.xml', MyTree, {'MyTree', [], 'This is a global comment'}); 583 | type('test.xml') 584 | %% 585 | % *Same operation using Apache Xerces XML engine* 586 | % gives even nicer results. 587 | Pref=[]; Pref.XmlEngine = 'Xerces'; % use Xerces xml generator directly 588 | xml_write('test.xml', MyTree, {'MyTree', [], 'This is a global comment'}, Pref); 589 | type('test.xml') 590 | 591 | %% 592 | % *Comments in XML top level (method #2)* 593 | % This method adds an extra top layer to the struct 'tree' and sets 594 | % "Pref.RootOnly = false", which informs the function about the extra 595 | % layer. Notice that RootName is also saved as a part of 596 | % the 'tree', and does not have to be passed in separately. 597 | MyTree=[]; 598 | MyTree.COMMENT = 'This is a global comment'; 599 | MyTree.MyTest.MyNumber = 13; 600 | MyTree.MyTest.MyString = 'Hello World'; 601 | Pref=[]; Pref.RootOnly = false; 602 | xml_write('test.xml', MyTree, [], Pref); 603 | type('test.xml') 604 | %% 605 | % *Same operation using Apache Xerces XML engine* 606 | Pref=[]; Pref.XmlEngine = 'Xerces'; % use Xerces xml generator directly 607 | Pref.RootOnly = false; 608 | xml_write('test.xml', MyTree, [], Pref); 609 | type('test.xml') 610 | 611 | %% Write XML files with PROCESSING_INSTRUCTIONs 612 | % Insertion of Processing Instructions is done through use of special 613 | % PROCESSING_INSTRUCTION field, which stores the instruction string. The 614 | % string has to be in 'target data' format separated by space. 615 | MyTree=[]; 616 | MyTree.PROCESSING_INSTRUCTION = 'xml-stylesheet type="a" href="foo"'; 617 | MyTree.MyNumber = 13; 618 | MyTree.MyString = 'Hello World'; 619 | xml_write('test.xml', MyTree); 620 | type('test.xml') 621 | 622 | %% 623 | % *Same operation using Apache Xerces XML engine* 624 | Pref=[]; Pref.XmlEngine = 'Xerces'; % use Xerces xml generator directly 625 | xml_write('test.xml', MyTree, 'MyTree', Pref); 626 | type('test.xml') 627 | 628 | %% 629 | % *PROCESSING_INSTRUCTIONs in XML top level (method #1)* 630 | % This method uses cell array 631 | MyTree=[]; 632 | MyTree.MyNumber = 13; 633 | MyTree.MyString = 'Hello World'; 634 | xml_write('test.xml', MyTree, {'MyTree', 'xml-stylesheet type="a" href="foo"'}); 635 | type('test.xml') 636 | %% 637 | % *Same operation using Apache Xerces XML engine* 638 | Pref=[]; Pref.XmlEngine = 'Xerces'; % use Xerces xml generator directly 639 | xml_write('test.xml', MyTree, {'MyTree', 'xml-stylesheet type="a" href="foo"'}, Pref); 640 | type('test.xml') 641 | 642 | %% 643 | % *PROCESSING_INSTRUCTIONs in XML top level (method #2)* 644 | % This method adds an extra top layer to the struct 'tree' and sets 645 | % pref.RootOnly=false, which informs the function about the extra 646 | % layer. Notice that RootName is also saved as a part of 647 | % the 'tree', and does not have to be passed in separately. 648 | MyTree=[]; 649 | MyTree.PROCESSING_INSTRUCTION = 'xml-stylesheet type="a" href="foo"'; 650 | MyTree.MyTest.MyNumber = 13; 651 | MyTree.MyTest.MyString = 'Hello World'; 652 | Pref=[]; Pref.RootOnly = false; 653 | xml_write('test.xml', MyTree, [], Pref); 654 | type('test.xml') 655 | %% 656 | % *Same operation using Apache Xerces XML engine* 657 | Pref=[]; Pref.XmlEngine = 'Xerces'; % use Xerces xml generator directly 658 | Pref.RootOnly = false; 659 | xml_write('test.xml', MyTree, 'MyTree', Pref); 660 | type('test.xml') 661 | 662 | %% Write XML files with CDATA Sections 663 | % "In an XML document a CDATA (Character DATA) section is a section of 664 | % element content that is marked for the parser to interpret as only 665 | % character data, not markup." (from Wikipedia) 666 | % To insert CDATA Sections one use special CDATA_SECTION field, 667 | % which stores the instruction string. Note that MATLAB's xmlwrite created 668 | % wrong xml code for CDATA section 669 | MyTree=[]; 670 | MyTree.CDATA_SECTION = 'txt'; 671 | MyTree.MyNumber = 13; 672 | MyTree.MyString = 'Hello World'; 673 | xml_write('test.xml', MyTree); 674 | type('test.xml') 675 | %% 676 | % *Same operation using Apache Xerces XML engine produces correct results* 677 | Pref=[]; Pref.XmlEngine = 'Xerces'; % use Xerces xml generator directly 678 | xml_write('test.xml', MyTree, 'MyTree', Pref); 679 | type('test.xml') 680 | 681 | %% Write XML files with special characters in TAG names 682 | % The input to xml_write requires that all tags one wants in XML document 683 | % have to be encoded as field names of MATLAB's struct's. Matlab has a lot 684 | % of restrictions on variable names. This section is about XML tags with 685 | % names not allowed as MATLAB variables, or more specifically with 686 | % characters allowed as xml tag names but not allowed as MATLAB variable 687 | % names. Characters like that can be replaced by their hexadecimal 688 | % representation just as it is done by genvarname function. Alternative way 689 | % of writing the first example is: 690 | MyTree=[]; 691 | MyTree.('MyNumber') = 13; % same as MyTree.MyNumber = 13; 692 | MyTree.MyString.CONTENT = 'Hello World'; 693 | MyTree.MyString.ATTRIBUTE.('Num') = 2; % same as MyTree.MyString.ATTRIBUTE.Num = 2; 694 | xml_write('test.xml', MyTree); 695 | type('test.xml') 696 | 697 | %% 698 | % *This approach fails for some characters like dash '-', colon ':', and 699 | % international characters.* 700 | MyTree=[]; 701 | try 702 | MyTree.('My-Number') = 13; 703 | MyTree.MyString.CONTENT = 'Hello World'; 704 | MyTree.MyString.ATTRIBUTE.('Num_?') = 2; 705 | catch %#ok 706 | err = lasterror; %#ok 707 | disp(err.message); 708 | end 709 | 710 | %% 711 | % It can be overcome by replacing offending characters with their 712 | % hexadecimal representation. That can be done manually or with use of 713 | % genvarname function. Note that MATLAB 'type' function does not show 714 | % correctly '? letter in xml file, but opening the file in editor shows 715 | % that it is correct. 716 | MyTree=[]; 717 | MyTree.(genvarname('My-Number')) = 13; 718 | MyTree.MyString.CONTENT = 'Hello World'; 719 | MyTree.MyString.ATTRIBUTE.Num_0xF6 = 2; 720 | gen_object_display(MyTree); 721 | xml_write('test.xml', MyTree); 722 | type('test.xml') 723 | 724 | %% 725 | % *Also two of the characters '-' and ':' can be encoded by a special strings: 726 | % '_DASH_' and '_COLON_' respectively* 727 | MyTree=[]; 728 | MyTree.My_DASH_Number = 13; 729 | MyTree.MyString.CONTENT = 'Hello World'; 730 | MyTree.MyString.ATTRIBUTE.Num0xF6 = 2; 731 | xml_write('test.xml', MyTree); 732 | type('test.xml') 733 | 734 | %% Write XML files with Namespaces 735 | % No extra special fields are needed to define XML namespaces, only colon 736 | % character written using '0x3A' or '_COLON_'. Below is an 737 | % example of a namespace definition 738 | MyTree=[]; 739 | MyTree.f_COLON_child.ATTRIBUTE.xmlns_COLON_f = 'http://www.foo.com'; 740 | MyTree.f_COLON_child.f_COLON_MyNumber = 13; 741 | MyTree.f_COLON_child.f_COLON_MyString = 'Hello World'; 742 | xml_write('test.xml', MyTree, 'MyTree'); 743 | type('test.xml') 744 | %% 745 | % *Same operation using Apache Xerces XML engine* 746 | Pref=[]; Pref.XmlEngine = 'Xerces'; % use Xerces xml generator directly 747 | xml_write('test.xml', MyTree, 'f_COLON_MyTree', Pref); 748 | type('test.xml') 749 | 750 | %% "Pref.KeepNS" flag in "xml_read" 751 | % Thise option allow keeping or exclusion of namespaces in tag names. 752 | % By default the namespace data is kept but it produces much longer field 753 | % names in the output structure. Ignoring namespace will produce more 754 | % readible output. 755 | % Perform default read of file with namespace 756 | tree = xml_read('test.xml'); 757 | gen_object_display(tree); 758 | 759 | %% 760 | % Now the same operation with KeepNS = false. 761 | Pref=[]; Pref.KeepNS = false; % do not read attributes 762 | tree = xml_read('test.xml', Pref); 763 | gen_object_display(tree); 764 | 765 | %% Read XML files with special node types 766 | % Display and read the file, then show the data structure. Note that 767 | % MATLAB 'type' function shows '? letter incorrectly as 'A? in xml file, 768 | % but opening the file in editor shows that it is correct. 769 | fprintf('Test xml file:\n'); 770 | type('test_file.xml') 771 | %% 772 | % Read only the Root Element (default) 773 | [tree GlobalTextNodes] = xml_read('test_file.xml'); 774 | fprintf('Global Data (Root name, Global Processing Instructions and Global Comments):\n'); 775 | disp(GlobalTextNodes') 776 | fprintf('\nStructure read from the file (uncludes COMMENT and CDATA sections):\n'); 777 | gen_object_display(tree); 778 | %% 779 | % Read the whole tree including global Comments and Processing Instructions 780 | Pref=[]; Pref.RootOnly = false; 781 | [tree GlobalTextNodes] = xml_read('test_file.xml', Pref); 782 | fprintf('Global Data (Root name, Global Processing Instructions and Global Comments):\n'); 783 | disp(GlobalTextNodes') 784 | fprintf('\nStructure read from the file (uncludes COMMENT and CDATA sections):\n'); 785 | gen_object_display(tree); 786 | 787 | %% "Pref.ReadAttr" flag in "xml_read" (control handling of nodes with attributes) 788 | % Those option allow exclusion of attributes 789 | Pref=[]; Pref.ReadAttr = false; % do not read attributes 790 | tree = xml_read('test_file.xml', Pref); 791 | gen_object_display(tree); 792 | 793 | %% "Pref.ReadSpec" flag in "xml_read" 794 | % Those option allow exclusion of special nodes, like 795 | % comments, processing instructions, CData sections, etc. 796 | Pref=[]; Pref.ReadSpec = false; % do not read special node types 797 | tree = xml_read('test_file.xml', Pref); 798 | gen_object_display(tree); 799 | 800 | %% "Pref.RootOnly" flag in "xml_read" 801 | % As it was shown in previous examples RootOnly parameter can be used to 802 | % capture global (top level) special nodes (like COMMENTs and 803 | % PROCESSING_INSTRUCTIONs) which are ignored by default 804 | Pref=[]; Pref.RootOnly = false; % do not read special node types 805 | tree = xml_read('test_file.xml', Pref); 806 | gen_object_display(tree); 807 | 808 | %% "Pref.RootOnly" flag in "xml_write" 809 | % Writing previously read tree with default "Pref.RootOnly = true" gives 810 | % wrong output file 811 | Pref=[]; Pref.RootOnly = true; % do not read special node types 812 | xml_write('test.xml', tree, [], Pref); 813 | fprintf('Test xml file:\n'); 814 | type('test.xml') 815 | %% 816 | % Writing the same tree with "Pref.RootOnly = false" gives correct output 817 | Pref=[]; Pref.RootOnly = false; % do not read special node types 818 | xml_write('test.xml', tree, [], Pref); 819 | fprintf('Test xml file:\n'); 820 | type('test.xml') 821 | 822 | %% "Pref.NumLevels" flag in "xml_read" 823 | % This parameter allows user to skip parts of the tree in order to save 824 | % time and memory. Usefull only in a rare case when a small portion of 825 | % large XML file is needed. 826 | % 827 | % Create test tile 828 | MyTree = []; 829 | MyTree.Level1 = 1; 830 | MyTree.Level1_.Level2 = 2; 831 | MyTree.Level1_.Level2_.Level3 = 3; 832 | MyTree.Level1_.Level2_.Level3_.Level4 = 4; 833 | xml_write('test.xml', MyTree); 834 | fprintf('Test xml file:\n'); 835 | type('test.xml') 836 | %% 837 | % *Use Default ("Pref.NumLevels = infinity") setting* 838 | tree = xml_read('test.xml'); 839 | gen_object_display(tree); 840 | %% 841 | % *Limit the read to only 2 levels* 842 | Pref=[]; Pref.NumLevels = 2; 843 | tree = xml_read('test.xml', Pref); 844 | gen_object_display(tree); 845 | 846 | 847 | 848 | 849 | %% Create DOM object based on a Struct using "xml_write" 850 | % *Create Struct tree* 851 | MyTree=[]; 852 | MyTree.MyNumber = 13; 853 | MyTree.MyString = 'Hello World'; 854 | %% 855 | % *Convert Struct to DOM object using xml_write* 856 | DOM = xml_write([], MyTree); 857 | xmlwrite('test.xml', DOM); % Save DOM object using MATLAB function 858 | type('test.xml') 859 | 860 | %% Convert DOM object to Struct using "xml_read" 861 | DOM = xmlread('test.xml'); % Read DOM object using MATLAB function 862 | [tree treeName] = xml_read(DOM); % Convert DOM object to Struct 863 | disp([treeName{1} ' =']) 864 | gen_object_display(tree) 865 | 866 | %% Write XML file based on a DOM using "xml_write_xerces" 867 | xmlwrite_xerces('test.xml', DOM); % Save DOM object using Xerces library 868 | type('test.xml') 869 | 870 | %% Write XML to string instead of a file 871 | DOM = xml_write([], MyTree); 872 | str = xmlwrite(DOM); 873 | disp(str) 874 | 875 | %% Write XML file with embedded binary data encoded as Base64 (using java version) 876 | fid = fopen('football.jpg', 'rb'); 877 | raw1 = uint8(fread(fid, 'uint8')); % read image file as a raw binary 878 | fclose(fid); 879 | 880 | MyTree=[]; 881 | MyTree.Size = 13; 882 | MyTree.MyString = 'Hello World'; % simple case 883 | MyTree.MyImage.ATTRIBUTE.EncodingMIMEType = 'base64'; 884 | MyTree.MyImage.CONTENT = base64encode(raw1,'java');% perform base64 encoding of the binary data 885 | xml_write('test.xml', MyTree); % write xml file 886 | 887 | %% Read XML file with embedded binary data encoded as Base64 (using java version) 888 | tree = xml_read('test.xml', Pref); % read xml file 889 | raw = base64decode(tree.MyImage.CONTENT, '', 'java'); % convert xml image to raw binary 890 | fid = fopen('MyFootball.jpg', 'wb'); 891 | fwrite(fid, raw, 'uint8'); % dumb the raw binary to the hard disk 892 | fclose(fid); 893 | I = imread('MyFootball.jpg'); % read it as an image 894 | imshow(I); 895 | 896 | %% Write XML file with embedded binary data encoded as Base64 (simpler version using only matlab code 897 | % Notice that process of writing to xml stripped all end-of-lie characters 898 | % from base64 code. 899 | isChunked = true; % break into chunks 76 characters long 900 | url_safe = true; % 'base64url' encoding 901 | code = base64encode('license.txt', 'matlab', isChunked, url_safe); 902 | disp(code) 903 | MyTree=[]; 904 | MyTree.Size = 13; 905 | MyTree.MyString = 'Hello World'; 906 | MyTree.MyImage.ATTRIBUTE.EncodingMIMEType = 'base64'; 907 | MyTree.MyImage.CONTENT = code; % perform base64 encoding of the binary data 908 | xml_write('test.xml', MyTree); % write xml file 909 | type('test.xml') 910 | 911 | %% Read XML file with embedded binary data encoded as Base64 (simpler version using only matlab code 912 | tree = xml_read('test.xml', Pref); % read xml file 913 | base64decode(tree.MyImage.CONTENT, 'license2.txt', 'matlab'); % save xml image as raw binary 914 | type('license2.txt') -------------------------------------------------------------------------------- /xml_io_tools/code/xml_write.m: -------------------------------------------------------------------------------- 1 | function DOMnode = xml_write(filename, tree, RootName, Pref) 2 | %XML_WRITE Writes Matlab data structures to XML file 3 | % 4 | % DESCRIPTION 5 | % xml_write( filename, tree) Converts Matlab data structure 'tree' containing 6 | % cells, structs, numbers and strings to Document Object Model (DOM) node 7 | % tree, then saves it to XML file 'filename' using Matlab's xmlwrite 8 | % function. Optionally one can also use alternative version of xmlwrite 9 | % function which directly calls JAVA functions for XML writing without 10 | % MATLAB middleware. This function is provided as a patch to existing 11 | % bugs in xmlwrite (in R2006b). 12 | % 13 | % xml_write(filename, tree, RootName, Pref) allows you to specify 14 | % additional preferences about file format 15 | % 16 | % DOMnode = xml_write([], tree) same as above except that DOM node is 17 | % not saved to the file but returned. 18 | % 19 | % INPUT 20 | % filename file name 21 | % tree Matlab structure tree to store in xml file. 22 | % RootName String with XML tag name used for root (top level) node 23 | % Optionally it can be a string cell array storing: Name of 24 | % root node, document "Processing Instructions" data and 25 | % document "comment" string 26 | % Pref Other preferences: 27 | % Pref.ItemName - default 'item' - name of a special tag used to 28 | % itemize cell or struct arrays 29 | % Pref.XmlEngine - let you choose the XML engine. Currently default is 30 | % 'Xerces', which is using directly the apache xerces java file. 31 | % Other option is 'Matlab' which uses MATLAB's xmlwrite and its 32 | % XMLUtils java file. Both options create identical results except in 33 | % case of CDATA sections where xmlwrite fails. 34 | % Pref.CellItem - default 'true' - allow cell arrays to use 'item' 35 | % notation. See below. 36 | % Pref.RootOnly - default true - output variable 'tree' corresponds to 37 | % xml file root element, otherwise it correspond to the whole file. 38 | % Pref.StructItem - default 'true' - allow arrays of structs to use 39 | % 'item' notation. For example "Pref.StructItem = true" gives: 40 | % 41 | % 42 | % ... <\item> 43 | % ... <\item> 44 | % <\b> 45 | % <\a> 46 | % while "Pref.StructItem = false" gives: 47 | % 48 | % ... <\b> 49 | % ... <\b> 50 | % <\a> 51 | % 52 | % 53 | % Several special xml node types can be created if special tags are used 54 | % for field names of 'tree' nodes: 55 | % - node.CONTENT - stores data section of the node if other fields 56 | % (usually ATTRIBUTE are present. Usually data section is stored 57 | % directly in 'node'. 58 | % - node.ATTRIBUTE.name - stores node's attribute called 'name'. 59 | % - node.COMMENT - create comment child node from the string. For global 60 | % comments see "RootName" input variable. 61 | % - node.PROCESSING_INSTRUCTIONS - create "processing instruction" child 62 | % node from the string. For global "processing instructions" see 63 | % "RootName" input variable. 64 | % - node.CDATA_SECTION - stores node's CDATA section (string). Only works 65 | % if Pref.XmlEngine='Xerces'. For more info, see comments of F_xmlwrite. 66 | % - other special node types like: document fragment nodes, document type 67 | % nodes, entity nodes and notation nodes are not being handled by 68 | % 'xml_write' at the moment. 69 | % 70 | % OUTPUT 71 | % DOMnode Document Object Model (DOM) node tree in the format 72 | % required as input to xmlwrite. (optional) 73 | % 74 | % EXAMPLES: 75 | % MyTree=[]; 76 | % MyTree.MyNumber = 13; 77 | % MyTree.MyString = 'Hello World'; 78 | % xml_write('test.xml', MyTree); 79 | % type('test.xml') 80 | % %See also xml_tutorial.m 81 | % 82 | % See also 83 | % xml_read, xmlread, xmlwrite 84 | % 85 | % Written by Jarek Tuszynski, SAIC, jaroslaw.w.tuszynski_at_saic.com 86 | 87 | %% Check Matlab Version 88 | v = ver('MATLAB'); 89 | v = str2double(regexp(v.Version, '\d.\d','match','once')); 90 | if (v<7) 91 | error('Your MATLAB version is too old. You need version 7.0 or newer.'); 92 | end 93 | 94 | %% default preferences 95 | DPref.TableName = {'tr','td'}; % name of a special tags used to itemize 2D cell arrays 96 | DPref.ItemName = 'item'; % name of a special tag used to itemize 1D cell arrays 97 | DPref.StructItem = true; % allow arrays of structs to use 'item' notation 98 | DPref.CellItem = true; % allow cell arrays to use 'item' notation 99 | DPref.StructTable= 'Html'; 100 | DPref.CellTable = 'Html'; 101 | DPref.XmlEngine = 'Matlab'; % use matlab provided XMLUtils 102 | %DPref.XmlEngine = 'Xerces'; % use Xerces xml generator directly 103 | DPref.PreserveSpace = false; % Preserve or delete spaces at the beggining and the end of stings? 104 | RootOnly = true; % Input is root node only 105 | GlobalProcInst = []; 106 | GlobalComment = []; 107 | GlobalDocType = []; 108 | 109 | %% read user preferences 110 | if (nargin>3) 111 | if (isfield(Pref, 'TableName' )), DPref.TableName = Pref.TableName; end 112 | if (isfield(Pref, 'ItemName' )), DPref.ItemName = Pref.ItemName; end 113 | if (isfield(Pref, 'StructItem')), DPref.StructItem = Pref.StructItem; end 114 | if (isfield(Pref, 'CellItem' )), DPref.CellItem = Pref.CellItem; end 115 | if (isfield(Pref, 'CellTable')), DPref.CellTable = Pref.CellTable; end 116 | if (isfield(Pref, 'StructTable')), DPref.StructTable= Pref.StructTable; end 117 | if (isfield(Pref, 'XmlEngine' )), DPref.XmlEngine = Pref.XmlEngine; end 118 | if (isfield(Pref, 'RootOnly' )), RootOnly = Pref.RootOnly; end 119 | if (isfield(Pref, 'PreserveSpace')), DPref.PreserveSpace = Pref.PreserveSpace; end 120 | end 121 | if (nargin<3 || isempty(RootName)), RootName=inputname(2); end 122 | if (isempty(RootName)), RootName='ROOT'; end 123 | if (iscell(RootName)) % RootName also stores global text node data 124 | rName = RootName; 125 | RootName = char(rName{1}); 126 | if (length(rName)>1), GlobalProcInst = char(rName{2}); end 127 | if (length(rName)>2), GlobalComment = char(rName{3}); end 128 | if (length(rName)>3), GlobalDocType = char(rName{4}); end 129 | end 130 | if(~RootOnly && isstruct(tree)) % if struct than deal with each field separatly 131 | fields = fieldnames(tree); 132 | for i=1:length(fields) 133 | field = fields{i}; 134 | x = tree(1).(field); 135 | if (strcmp(field, 'COMMENT')) 136 | GlobalComment = x; 137 | elseif (strcmp(field, 'PROCESSING_INSTRUCTION')) 138 | GlobalProcInst = x; 139 | elseif (strcmp(field, 'DOCUMENT_TYPE')) 140 | GlobalDocType = x; 141 | else 142 | RootName = field; 143 | t = x; 144 | end 145 | end 146 | tree = t; 147 | end 148 | 149 | %% Initialize jave object that will store xml data structure 150 | RootName = varName2str(RootName); 151 | if (~isempty(GlobalDocType)) 152 | % n = strfind(GlobalDocType, ' '); 153 | % if (~isempty(n)) 154 | % dtype = com.mathworks.xml.XMLUtils.createDocumentType(GlobalDocType); 155 | % end 156 | % DOMnode = com.mathworks.xml.XMLUtils.createDocument(RootName, dtype); 157 | warning('xml_io_tools:write:docType', ... 158 | 'DOCUMENT_TYPE node was encountered which is not supported yet. Ignoring.'); 159 | end 160 | DOMnode = com.mathworks.xml.XMLUtils.createDocument(RootName); 161 | 162 | 163 | %% Use recursive function to convert matlab data structure to XML 164 | root = DOMnode.getDocumentElement; 165 | struct2DOMnode(DOMnode, root, tree, DPref.ItemName, DPref); 166 | 167 | %% Remove the only child of the root node 168 | root = DOMnode.getDocumentElement; 169 | Child = root.getChildNodes; % create array of children nodes 170 | nChild = Child.getLength; % number of children 171 | if (nChild==1) 172 | node = root.removeChild(root.getFirstChild); 173 | while(node.hasChildNodes) 174 | root.appendChild(node.removeChild(node.getFirstChild)); 175 | end 176 | while(node.hasAttributes) % copy all attributes 177 | root.setAttributeNode(node.removeAttributeNode(node.getAttributes.item(0))); 178 | end 179 | end 180 | 181 | %% Save exotic Global nodes 182 | if (~isempty(GlobalComment)) 183 | DOMnode.insertBefore(DOMnode.createComment(GlobalComment), DOMnode.getFirstChild()); 184 | end 185 | if (~isempty(GlobalProcInst)) 186 | n = strfind(GlobalProcInst, ' '); 187 | if (~isempty(n)) 188 | proc = DOMnode.createProcessingInstruction(GlobalProcInst(1:(n(1)-1)),... 189 | GlobalProcInst((n(1)+1):end)); 190 | DOMnode.insertBefore(proc, DOMnode.getFirstChild()); 191 | end 192 | end 193 | % Not supported yet as the code below does not work 194 | % if (~isempty(GlobalDocType)) 195 | % n = strfind(GlobalDocType, ' '); 196 | % if (~isempty(n)) 197 | % dtype = DOMnode.createDocumentType(GlobalDocType); 198 | % DOMnode.insertBefore(dtype, DOMnode.getFirstChild()); 199 | % end 200 | % end 201 | 202 | %% save java DOM tree to XML file 203 | if (~isempty(filename)) 204 | if (strcmpi(DPref.XmlEngine, 'Xerces')) 205 | xmlwrite_xerces(filename, DOMnode); 206 | else 207 | xmlwrite(filename, DOMnode); 208 | end 209 | end 210 | 211 | 212 | %% ======================================================================= 213 | % === struct2DOMnode Function =========================================== 214 | % ======================================================================= 215 | function [] = struct2DOMnode(xml, parent, s, TagName, Pref) 216 | % struct2DOMnode is a recursive function that converts matlab's structs to 217 | % DOM nodes. 218 | % INPUTS: 219 | % xml - jave object that will store xml data structure 220 | % parent - parent DOM Element 221 | % s - Matlab data structure to save 222 | % TagName - name to be used in xml tags describing 's' 223 | % Pref - preferenced 224 | % OUTPUT: 225 | % parent - modified 'parent' 226 | 227 | % perform some conversions 228 | if (ischar(s) && min(size(s))>1) % if 2D array of characters 229 | s=cellstr(s); % than convert to cell array 230 | end 231 | % if (strcmp(TagName, 'CONTENT')) 232 | % while (iscell(s) && length(s)==1), s = s{1}; end % unwrap cell arrays of length 1 233 | % end 234 | TagName = varName2str(TagName); 235 | 236 | %% == node is a 2D cell array == 237 | % convert to some other format prior to further processing 238 | nDim = nnz(size(s)>1); % is it a scalar, vector, 2D array, 3D cube, etc? 239 | if (iscell(s) && nDim==2 && strcmpi(Pref.CellTable, 'Matlab')) 240 | s = var2str(s, Pref.PreserveSpace); 241 | end 242 | if (nDim==2 && (iscell (s) && strcmpi(Pref.CellTable, 'Vector')) || ... 243 | (isstruct(s) && strcmpi(Pref.StructTable, 'Vector'))) 244 | s = s(:); 245 | end 246 | if (nDim>2), s = s(:); end % can not handle this case well 247 | nItem = numel(s); 248 | nDim = nnz(size(s)>1); % is it a scalar, vector, 2D array, 3D cube, etc? 249 | 250 | %% == node is a cell == 251 | if (iscell(s)) % if this is a cell or cell array 252 | if ((nDim==2 && strcmpi(Pref.CellTable,'Html')) || (nDim< 2 && Pref.CellItem)) 253 | % if 2D array of cells than can use HTML-like notation or if 1D array 254 | % than can use item notation 255 | if (strcmp(TagName, 'CONTENT')) % CONTENT nodes already have ... 256 | array2DOMnode(xml, parent, s, Pref.ItemName, Pref ); % recursive call 257 | else 258 | node = xml.createElement(TagName); % ... 259 | array2DOMnode(xml, node, s, Pref.ItemName, Pref ); % recursive call 260 | parent.appendChild(node); 261 | end 262 | else % use ...<\TagName> ...<\TagName> notation 263 | array2DOMnode(xml, parent, s, TagName, Pref ); % recursive call 264 | end 265 | %% == node is a struct == 266 | elseif (isstruct(s)) % if struct than deal with each field separatly 267 | if ((nDim==2 && strcmpi(Pref.StructTable,'Html')) || (nItem>1 && Pref.StructItem)) 268 | % if 2D array of structs than can use HTML-like notation or 269 | % if 1D array of structs than can use 'items' notation 270 | node = xml.createElement(TagName); 271 | array2DOMnode(xml, node, s, Pref.ItemName, Pref ); % recursive call 272 | parent.appendChild(node); 273 | elseif (nItem>1) % use ...<\TagName> ...<\TagName> notation 274 | array2DOMnode(xml, parent, s, TagName, Pref ); % recursive call 275 | else % otherwise save each struct separatelly 276 | fields = fieldnames(s); 277 | node = xml.createElement(TagName); 278 | for i=1:length(fields) % add field by field to the node 279 | field = fields{i}; 280 | x = s.(field); 281 | switch field 282 | case {'COMMENT', 'CDATA_SECTION', 'PROCESSING_INSTRUCTION'} 283 | if iscellstr(x) % cell array of strings -> add them one by one 284 | array2DOMnode(xml, node, x(:), field, Pref ); % recursive call will modify 'node' 285 | elseif ischar(x) % single string -> add it 286 | struct2DOMnode(xml, node, x, field, Pref ); % recursive call will modify 'node' 287 | else % not a string - Ignore 288 | warning('xml_io_tools:write:badSpecialNode', ... 289 | ['Struct field named ',field,' encountered which was not a string. Ignoring.']); 290 | end 291 | case 'ATTRIBUTE' % set attributes of the node 292 | if (isempty(x)), continue; end 293 | if (isstruct(x)) 294 | attName = fieldnames(x); % get names of all the attributes 295 | for k=1:length(attName) % attach them to the node 296 | att = xml.createAttribute(varName2str(attName(k))); 297 | att.setValue(var2str(x.(attName{k}),Pref.PreserveSpace)); 298 | node.setAttributeNode(att); 299 | end 300 | else 301 | warning('xml_io_tools:write:badAttribute', ... 302 | 'Struct field named ATTRIBUTE encountered which was not a struct. Ignoring.'); 303 | end 304 | otherwise % set children of the node 305 | struct2DOMnode(xml, node, x, field, Pref ); % recursive call will modify 'node' 306 | end 307 | end % end for i=1:nFields 308 | parent.appendChild(node); 309 | end 310 | %% == node is a leaf node == 311 | else % if not a struct and not a cell than it is a leaf node 312 | switch TagName % different processing depending on desired type of the node 313 | case 'COMMENT' % create comment node 314 | com = xml.createComment(s); 315 | parent.appendChild(com); 316 | case 'CDATA_SECTION' % create CDATA Section 317 | cdt = xml.createCDATASection(s); 318 | parent.appendChild(cdt); 319 | case 'PROCESSING_INSTRUCTION' % set attributes of the node 320 | OK = false; 321 | if (ischar(s)) 322 | n = strfind(s, ' '); 323 | if (~isempty(n)) 324 | proc = xml.createProcessingInstruction(s(1:(n(1)-1)),s((n(1)+1):end)); 325 | parent.insertBefore(proc, parent.getFirstChild()); 326 | OK = true; 327 | end 328 | end 329 | if (~OK) 330 | warning('xml_io_tools:write:badProcInst', ... 331 | ['Struct field named PROCESSING_INSTRUCTION need to be',... 332 | ' a string, for example: xml-stylesheet type="text/css" ', ... 333 | 'href="myStyleSheet.css". Ignoring.']); 334 | end 335 | case 'CONTENT' % this is text part of already existing node 336 | txt = xml.createTextNode(var2str(s, Pref.PreserveSpace)); % convert to text 337 | parent.appendChild(txt); 338 | otherwise % I guess it is a regular text leaf node 339 | txt = xml.createTextNode(var2str(s, Pref.PreserveSpace)); 340 | node = xml.createElement(TagName); 341 | node.appendChild(txt); 342 | parent.appendChild(node); 343 | end 344 | end % of struct2DOMnode function 345 | 346 | %% ======================================================================= 347 | % === array2DOMnode Function ============================================ 348 | % ======================================================================= 349 | function [] = array2DOMnode(xml, parent, s, TagName, Pref) 350 | % Deal with 1D and 2D arrays of cell or struct. Will modify 'parent'. 351 | nDim = nnz(size(s)>1); % is it a scalar, vector, 2D array, 3D cube, etc? 352 | switch nDim 353 | case 2 % 2D array 354 | for r=1:size(s,1) 355 | subnode = xml.createElement(Pref.TableName{1}); 356 | for c=1:size(s,2) 357 | v = s(r,c); 358 | if iscell(v), v = v{1}; end 359 | struct2DOMnode(xml, subnode, v, Pref.TableName{2}, Pref ); % recursive call 360 | end 361 | parent.appendChild(subnode); 362 | end 363 | case 1 %1D array 364 | for iItem=1:numel(s) 365 | v = s(iItem); 366 | if iscell(v), v = v{1}; end 367 | struct2DOMnode(xml, parent, v, TagName, Pref ); % recursive call 368 | end 369 | case 0 % scalar -> this case should never be called 370 | if ~isempty(s) 371 | if iscell(s), s = s{1}; end 372 | struct2DOMnode(xml, parent, s, TagName, Pref ); 373 | end 374 | end 375 | 376 | %% ======================================================================= 377 | % === var2str Function ================================================== 378 | % ======================================================================= 379 | function str = var2str(object, PreserveSpace) 380 | % convert matlab variables to a string 381 | switch (1) 382 | case isempty(object) 383 | str = ''; 384 | case (isnumeric(object) || islogical(object)) 385 | if ndims(object)>2, object=object(:); end % can't handle arrays with dimention > 2 386 | str=mat2str(object); % convert matrix to a string 387 | % mark logical scalars with [] (logical arrays already have them) so the xml_read 388 | % recognizes them as MATLAB objects instead of strings. Same with sparse 389 | % matrices 390 | if ((islogical(object) && isscalar(object)) || issparse(object)), 391 | str = ['[' str ']']; 392 | end 393 | if (isinteger(object)), 394 | str = ['[', class(object), '(', str ')]']; 395 | end 396 | case iscell(object) 397 | if ndims(object)>2, object=object(:); end % can't handle cell arrays with dimention > 2 398 | [nr nc] = size(object); 399 | obj2 = object; 400 | for i=1:length(object(:)) 401 | str = var2str(object{i}, PreserveSpace); 402 | if (ischar(object{i})), object{i} = ['''' object{i} '''']; else object{i}=str; end 403 | obj2{i} = [object{i} ',']; 404 | end 405 | for r = 1:nr, obj2{r,nc} = [object{r,nc} ';']; end 406 | obj2 = obj2.'; 407 | str = ['{' obj2{:} '}']; 408 | case isstruct(object) 409 | str=''; 410 | warning('xml_io_tools:write:var2str', ... 411 | 'Struct was encountered where string was expected. Ignoring.'); 412 | case isa(object, 'function_handle') 413 | str = ['[@' char(object) ']']; 414 | case ischar(object) 415 | str = object; 416 | otherwise 417 | str = char(object); 418 | end 419 | 420 | %% string clean-up 421 | str=str(:); str=str.'; % make sure this is a row vector of char's 422 | if (~isempty(str)) 423 | str(str<32|str==127)=' '; % convert no-printable characters to spaces 424 | if (~PreserveSpace) 425 | str = strtrim(str); % remove spaces from begining and the end 426 | str = regexprep(str,'\s+',' '); % remove multiple spaces 427 | end 428 | end 429 | 430 | %% ======================================================================= 431 | % === var2Namestr Function ============================================== 432 | % ======================================================================= 433 | function str = varName2str(str) 434 | % convert matlab variable names to a sting 435 | str = char(str); 436 | p = strfind(str,'0x'); 437 | if (~isempty(p)) 438 | for i=1:length(p) 439 | before = str( p(i)+(0:3) ); % string to replace 440 | after = char(hex2dec(before(3:4))); % string to replace with 441 | str = regexprep(str,before,after, 'once', 'ignorecase'); 442 | p=p-3; % since 4 characters were replaced with one - compensate 443 | end 444 | end 445 | str = regexprep(str,'_COLON_',':', 'once', 'ignorecase'); 446 | str = regexprep(str,'_DASH_' ,'-', 'once', 'ignorecase'); 447 | 448 | -------------------------------------------------------------------------------- /xml_io_tools/code/xmlwrite_xerces.m: -------------------------------------------------------------------------------- 1 | function varargout=xmlwrite_xerces(varargin) 2 | %XMLWRITE_XERCES Serialize an XML Document Object Model node using Xerces parser. 3 | % xmlwrite_xerces(FILENAME,DOMNODE) serializes the DOMNODE to file FILENAME. 4 | % 5 | % The function xmlwrite_xerces is very similar the Matlab function xmlwrite 6 | % but works directly with the XERCES java classes (written by Apache XML 7 | % Project) instead of the XMLUtils class created by Mathworks. Xerces files 8 | % are provided in standard MATLAB instalation and live in root\java\jarext 9 | % directory. 10 | % 11 | % Written by A.Amaro (02-22-2007) and generously donated to xml_io_tools. 12 | % This function is needed as a work-around for a bug in XMLUtils library 13 | % which can not write CDATA SECTION nodes correctly. Also Xerces and 14 | % XMLUtils libraries handle namespaces differently. 15 | % 16 | % Examples: 17 | % % See xmlwrite examples this function have almost identical behavior. 18 | % 19 | % Advanced use: 20 | % FILENAME can also be a URN, java.io.OutputStream or java.io.Writer object 21 | % SOURCE can also be a SAX InputSource, JAXP Source, InputStream, or 22 | % Reader object 23 | 24 | returnString = false; 25 | if length(varargin)==1 26 | returnString = true; 27 | result = java.io.StringWriter; 28 | source = varargin{1}; 29 | else 30 | result = varargin{1}; 31 | if ischar(result) 32 | % Using the XERCES classes directly, is not needed to modify the 33 | % filename string. So I have commented this next line 34 | % result = F_xmlstringinput(result,false); 35 | end 36 | 37 | source = varargin{2}; 38 | if ischar(source) 39 | source = F_xmlstringinput(source,true); 40 | end 41 | end 42 | 43 | % SERIALIZATION OF THE DOM DOCUMENT USING XERCES CLASSES DIRECTLY 44 | 45 | % 1) create the output format according to the document definitions 46 | % and type 47 | objOutputFormat = org.apache.xml.serialize.OutputFormat(source); 48 | set(objOutputFormat,'Indenting','on'); 49 | 50 | % 2) create the output stream. In this case: an XML file 51 | objFile = java.io.File(result); 52 | objOutputStream = java.io.FileOutputStream(objFile); 53 | 54 | % 3) Create the Xerces Serializer object 55 | objSerializer= org.apache.xml.serialize.XMLSerializer(objOutputStream,objOutputFormat); 56 | 57 | % 4) Serialize to the XML files 58 | javaMethod('serialize',objSerializer,source); 59 | 60 | % 5) IMPORTANT! Delete the objects to liberate the XML file created 61 | objOutputStream.close; 62 | 63 | if returnString 64 | varargout{1}=char(result.toString); 65 | end 66 | 67 | %% ======================================================================== 68 | function out = F_xmlstringinput(xString,isFullSearch,varargin) 69 | % The function F_xmlstringinput is a copy of the private function: 70 | % 'xmlstringinput' that the original xmlwrite function uses. 71 | 72 | if isempty(xString) 73 | error('Filename is empty'); 74 | elseif ~isempty(findstr(xString,'://')) 75 | %xString is already a URL, most likely prefaced by file:// or http:// 76 | out = xString; 77 | return; 78 | end 79 | 80 | xPath=fileparts(xString); 81 | if isempty(xPath) 82 | if nargin<2 || isFullSearch 83 | out = which(xString); 84 | if isempty(out) 85 | error('xml:FileNotFound','File %s not found',xString); 86 | end 87 | else 88 | out = fullfile(pwd,xString); 89 | end 90 | else 91 | out = xString; 92 | if (nargin<2 || isFullSearch) && ~exist(xString,'file') 93 | %search to see if xString exists when isFullSearch 94 | error('xml:FileNotFound','File %s not found',xString); 95 | end 96 | end 97 | 98 | %Return as a URN 99 | if strncmp(out,'\\',2) 100 | % SAXON UNC filepaths need to look like file:///\\\server-name\ 101 | out = ['file:///\',out]; 102 | elseif strncmp(out,'/',1) 103 | % SAXON UNIX filepaths need to look like file:///root/dir/dir 104 | out = ['file://',out]; 105 | else 106 | % DOS filepaths need to look like file:///d:/foo/bar 107 | out = ['file:///',strrep(out,'\','/')]; 108 | end 109 | 110 | -------------------------------------------------------------------------------- /xml_io_tools/readme.txt: -------------------------------------------------------------------------------- 1 | code内代码是通用的xml格式互转,里面代码都不用管,只需add MATLAB path 路径下即可 --------------------------------------------------------------------------------