2016-07-22 10 views
1

私は、バイナリデータを含むセクションを持つxmlフォーマルファイルを読むことができます。例えば、ファイルは以下の通りである:バイナリデータを含むxmlファイルをMatlabに読み込むには? (VTK/VTUファイル)

<?xml version="1.0"?> 
<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian"> 
    <UnstructuredGrid> 
    <Piece NumberOfPoints="1941" NumberOfCells="11339"> 
     <PointData> 
     <DataArray type="Float64" Name="magnetic field strength" NumberOfComponents="3" format="appended" offset="0"/> 
     <DataArray type="Float64" Name="magnetic flux density" NumberOfComponents="3" format="appended" offset="46588"/> 
     <DataArray type="Float64" Name="magnetic vector potential" NumberOfComponents="3" format="appended" offset="93176"/> 
     </PointData> 
     <CellData> 
     <DataArray type="Int32" Name="GeometryIds" format="appended" offset="139764"/> 
     </CellData> 
     <Points> 
     <DataArray type="Float64" NumberOfComponents="3" format="appended" offset="185124"/> 
     </Points> 
     <Cells> 
     <DataArray type="Int32" Name="connectivity" format="appended" offset="231712"/> 
     <DataArray type="Int32" Name="offsets" format="appended" offset="403396"/> 
     <DataArray type="Int32" Name="types" format="appended" offset="448756"/> 
     </Cells> 
    </Piece> 
    </UnstructuredGrid> 
<AppendedData encoding="raw"> 
_�[email protected]�Loû[email protected]�`@!?�V7^[email protected]�D�C�[email protected]�b�[email protected]���Y�[email protected]�r <snip> 
</AppendedData> 
</VTKFile> 

これは.vtu拡張が使用されるVTKデータファイル、具体的に構造化されていないGIDタイプ、です。これのフォーマットは通常のxmlですが、セクション 'AppendedData'にアンダースコアとバイナリデータが続く場合、xmlはこのデータの各データシーケンスの開始位置と終了位置を示します。

Matlabのxmlreadはこのファイルを読み取ることができません。バイナリ部分のためです。 、私は成功したファイルのXML部分に読むことができます(AppendedDataタグまで読むためにfgetlを使用して)しかし

[Fatal Error] elmer_3d_magnet_mesh.dat0001.vtu:24:1: Invalid byte 1 of 1-byte UTF-8 sequence. 
Error using xmlread (line 97) 
Java exception occurred: 
org.xml.sax.SAXParseException; systemId: file:/home/rcrozier/Sync/cad_models/elmer_3D_magnet/elmer_3d_magnet_mesh/elmer_3d_magnet_mesh.dat0001.vtu; lineNumber: 24; 
columnNumber: 1; Invalid byte 1 of 1-byte UTF-8 sequence. 
    at org.apache.xerces.parsers.DOMParser.parse(Unknown Source) 
    at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source) 
    at javax.xml.parsers.DocumentBuilder.parse(Unknown Source) 

:私は以下のエラーを取得します。次に、欠落している終了タグを追加し、xmlreadを使用してこれを読み取って、一時的なxmlファイルを作成することができます。次に、xmlを解析してデータ構造を決定することができます。これはバイナリ部分の読みをそのまま残します。最後に、xmlデータfgetlは、行の先頭に対応するファイル位置にアンダースコアを残します。

アンダースコア文字を無視してバイナリデータを読み取るにはどうすればよいですか?

実際には、ファイルの文字エンコードについて知らなくてもこれを行う方法を理解できないので、難しいことがわかっている「アンダースコア文字を無視する」部分です(この場合、UTF-8エンコードを知らない場合、file -biapplication/xml; charset=binaryを返します)。 fgetl

% open the file 
fid = fopen(filename, 'r'); 

% close file when we're done 
CC = onCleanup (@() fclose(fid)); 

xmlstrs = {fgetl(fid)}; 

find = 1; 

while ischar (xmlstrs{find}) 

    find = find + 1; 

    xmlstrs{find,1} = fgetl(fid); 

    if ~isempty(strfind (xmlstrs{find,1}, 'AppendedData')) 

     xmlstrs = [ xmlstrs; {'</AppendedData>'; '</VTKFile>'} ]; 

     % could get file position like this? how many bytes? 
     datapos = ftell (fid) + 4; 

     break; 
    end 

end 
+0

はあなたが関数fgetlにコードを追加してください可能性があり、あなたが書きました – Finn

+0

@Finn、私はそれを追加しました – crobar

答えて

0

でXML部分を取得するためのコードの位置を決定するまでの答え:それは興味深いものだ場合

、実際のVTKファイル形式の仕様はhere (pdf)

EDITを見つけることができます最初の行から読み取った文字のビット長を次のように計算することでした:

% open the file 
fid = fopen(filename, 'r'); 

% close file when we're done 
CC = onCleanup (@() fclose(fid)); 

xmlstrs = {fgetl(fid)}; 

firstlinebytes = ftell (fid) - 1; 

bytesperchar = round (firstlinebytes/numel (xmlstrs{1})); 

は、データセクションの最初のバイトの位置は、これは悪い文書化されてAppendedDataセクションの「生」タイプのデータを読み込むと、全体の答えではないことを、

datapos = ftell (fid) + bytesperchar; 

注意です。あなたはhere(むしろ「base64で」より)「生」データのフォーマットについての詳細情報を見つけますが、短い答えは、それは次のようにエンコードされますされています

_NNNN<data>NNNN<data>NNNN<data> 
^  ^  ^
1   2   3 

where each "NNNN" is an unsigned 32-bit integer, and <data> consists of 
a number of bytes equal to the preceding NNNN value. The corresponding 
DataArray elements must have format="appended" and offset attributes 
equal to the following: 

1.) offset="0" 
2.) offset="(4+NNNN1)" 
3.) offset="(4+NNNN1+4+NNNN2)" 
関連する問題