在 Matlab 的一個大型復雜專案中,我在編碼特殊字符和決議 XML 時遇到了一些麻煩。我已經隔離了問題,雖然我仍然不知道如何解決它,但我認為它與這個問題有關。
考慮以下 XML 檔案:
<?xml version="1.0"?>
<info>
<desc>
<channels>
<channel>
<label>accZ</label>
<unit>mg?</unit>
<type>ACC</type>
</channel>
</channels>
</desc>
</info>
假設 Unix 風格的行結尾,這個檔案包含 175 個位元組的資料。事實上,這就是我在 Notepad 中打開它時所說的。現在我有一個 XML 決議函式,我幾乎完全從 Mathworks 關于如何在 Matlab 中決議 XML 的解釋中復制了它(https://au.mathworks.com/help/matlab/ref/xmlread.html)。此功能運行良好,不是問題,僅出于完整性考慮才將其包含在內:
% parse a simplified (attribute-free) subset of XML into a MATLAB struct
function result = parse_xml_struct(str)
import org.xml.sax.InputSource
import javax.xml.parsers.*
import java.io.*
tmp = InputSource();
tmp.setCharacterStream(StringReader(str));
result = parseChildNodes(xmlread(tmp));
% this is part of xml2struct (slightly simplified)
function [children,ptext] = parseChildNodes(theNode)
% Recurse over node children.
children = struct;
ptext = [];
if theNode.hasChildNodes
childNodes = theNode.getChildNodes;
numChildNodes = childNodes.getLength;
for count = 1:numChildNodes
theChild = childNodes.item(count-1);
[text,name,childs] = getNodeData(theChild);
if (~strcmp(name,'#text') && ~strcmp(name,'#comment'))
if (isfield(children,name))
if (~iscell(children.(name)))
children.(name) = {children.(name)}; end
index = length(children.(name)) 1;
children.(name){index} = childs;
if(~isempty(text))
children.(name){index} = text; end
else
children.(name) = childs;
if(~isempty(text))
children.(name) = text; end
end
elseif (strcmp(name,'#text'))
if (~isempty(regexprep(text,'[\s]*','')))
if (isempty(ptext))
ptext = text;
else
ptext = [ptext text];
end
end
end
end
end
end
% this is part of xml2struct (slightly simplified)
function [text,name,childs] = getNodeData(theNode)
% Create structure of node info.
name = char(theNode.getNodeName);
if ~isvarname(name)
name = regexprep(name,'[-]','_dash_');
name = regexprep(name,'[:]','_colon_');
name = regexprep(name,'[.]','_dot_');
end
[childs,text] = parseChildNodes(theNode);
if (isempty(fieldnames(childs)))
try
text = char(theNode.getData);
catch
end
end
end
end
現在來測驗一下:
finfo = dir('xml_example');
sz = finfo.bytes
fid = fopen('xml_example', 'r', 'ieee-le.l64');
data = fread(fid, sz, '*char');
data_size = size(data)
h = parse_xml_struct(data);
unit = h.info.desc.channels.channel.unit
和輸出:
sz =
175
data_size =
173 1
unit =
'mg?'
所以不知何故,我最終得到了正確的輸出,但在此程序中丟失了 2 個位元組。我不明白為什么會這樣。
并且只是為了向自己證明是小下標 'o' 導致檔案大小與data陣列中的位元組數之間存在差異,我將其從 XML 檔案中洗掉并得到以下內容:
sz =
172
data_size =
172 1
unit =
'mg'
仍然是 xml 標簽的正確輸出,現在檔案大小和位元組陣列大小匹配。這是怎么回事?
更新
此外,如果我對 2 位元組長的符號運行相同的測驗,我仍然會出現壓縮現象。
<?xml version="1.0"?>
<info>
<desc>
<channels>
<channel>
<label>ωX</label>
<unit>mrad/s</unit>
<type>AUX</type>
</channel>
</channels>
</desc>
</info>
輸出:
sz =
175
data_size =
174 1
unit =
'ωX'
uj5u.com熱心網友回復:
該?符號為三個位元組長,采用 UTF-8 編碼 ( 0xE2 0x82 0x80)。在 MATLAB 內部,由于UTF-16 編碼(0x80 0x20小端),它實際上是兩個位元組。
然而,由于 a precisionof*char被賦予給fread,回傳的資料作為char陣列1回傳。對于char陣列,無論底層編碼如何,?在考慮其時都只是一個字符size:
如果
A是 型別的字符向量char,則size回傳行向量[1 M],其中M是字符數。
1我假設從freadifsizeA給出的匹配矩陣大小的強斷言(根據檔案)僅對數字資料有效,因為如上所述,位元組數和字符數不一定是一對一的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/389995.html
上一篇:按順序找出重復的數字?
