如何在MATLAB R2019中实现R2020b的readstruct与writestruct功能?
在MATLAB R2019中替代
readstruct和writestruct的实现方法 MATLAB R2019没有内置的readstruct和writestruct,但可以基于自带的xmlread和xmlwrite实现等效功能,下面是具体的自定义函数实现:
一、读取XML为结构体(替代readstruct)
通过xmlread加载XML文档,递归遍历DOM节点转换成结构体,处理节点属性、文本内容及同名子节点(自动转为结构体数组):
function S = my_readstruct(filename) doc = xmlread(filename); S = xmlnode2struct(doc.getDocumentElement()); end function s = xmlnode2struct(node) s = struct(); % 解析节点属性 attrs = node.getAttributes(); if attrs.getLength() > 0 for i = 0:attrs.getLength()-1 attr = attrs.item(i); s.(char(attr.getName())) = char(attr.getValue()); end end % 解析子节点 children = node.getChildNodes(); child_count = children.getLength(); % 处理纯文本节点 if child_count == 1 && children.item(0).getNodeType() == children.item(0).TEXT_NODE s = strtrim(char(children.item(0).getNodeValue())); return; end % 处理元素子节点 for i = 0:child_count-1 child = children.item(i); if child.getNodeType() == child.ELEMENT_NODE child_name = char(child.getNodeName()); child_struct = xmlnode2struct(child); % 同名子节点转为结构体数组 if isfield(s, child_name) if isstruct(s.(child_name)) && ~isarray(s.(child_name)) s.(child_name) = [s.(child_name), child_struct]; else s.(child_name) = [s.(child_name); child_struct]; end else s.(child_name) = child_struct; end end end end
使用方式和readstruct一致:
S = my_readstruct('your_file.xml');
二、将结构体写入XML(替代writestruct)
通过xmlwrite生成XML文档,递归将结构体字段转换为XML元素,支持属性、嵌套结构体及文本内容:
function my_writestruct(S, filename) % 默认根节点为root,若结构体有明确根字段可替换为对应名称 root_name = 'root'; if isstruct(S) && length(fieldnames(S)) == 1 root_name = fieldnames(S){1}; S = S.(root_name); end doc = com.mathworks.xml.XMLUtils.createDocument(root_name); root_node = doc.getDocumentElement(); struct2xmlnode(S, root_node, doc); xmlwrite(filename, doc); end function struct2xmlnode(s, parent_node, doc) if isstruct(s) for field_name = fieldnames(s)' field_val = s.(field_name{1}); node = doc.createElement(field_name{1}); % 处理带属性的字段(格式:s.field.Attribute = 属性结构体; s.field.Value = 内容) if isstruct(field_val) && isfield(field_val, 'Attribute') && isfield(field_val, 'Value') % 写入属性 attrs = field_val.Attribute; for attr_name = fieldnames(attrs)' node.setAttribute(attr_name{1}, char(attrs.(attr_name{1}))); end % 写入内容 val = field_val.Value; if ischar(val) || isstring(val) node.appendChild(doc.createTextNode(strtrim(char(val)))); elseif isnumeric(val) node.appendChild(doc.createTextNode(num2str(val))); end parent_node.appendChild(node); elseif isstruct(field_val) || iscell(field_val) % 递归处理嵌套结构体或结构体数组 if iscell(field_val) for idx = 1:length(field_val) struct2xmlnode(field_val{idx}, node, doc); end else struct2xmlnode(field_val, node, doc); end parent_node.appendChild(node); else % 写入纯文本内容 if ischar(field_val) || isstring(field_val) node.appendChild(doc.createTextNode(strtrim(char(field_val)))); elseif isnumeric(field_val) node.appendChild(doc.createTextNode(num2str(field_val))); end parent_node.appendChild(node); end end else % 直接写入文本节点 parent_node.appendChild(doc.createTextNode(strtrim(char(s)))); end end
使用方式和writestruct一致:
my_writestruct(S, 'output_file.xml');
注意事项
- 对于包含命名空间、特殊字符的复杂XML,可能需要根据实际场景调整函数逻辑
- 上述函数已覆盖
readstruct/writestruct的基础核心功能,常规XML读写场景可直接使用
内容的提问来源于stack exchange,提问作者Mo0nKizz
相关产品推荐
相关产品推荐

