转换XML文件到MATLAB结构,方便对数据的访问。
沃特Falkena(2020年)。xml2struct(//www.tatmou.com/matlabcentral/fileexchange/28518-xml2struct), MATLAB中央文件交换。检索。
1.8.0.0 | 修正了CDATA和注释结构字段中的小错误。 |
|
1.7.0.0 | 由于X. Mo和添加了对cdata和comments的支持而提高了速度。金宝app |
|
1.5.0.0 | 该函数现在将包含-的元素和属性名称替换为_dash_,。由…和 |
|
1.4.0.0 | 属性解析速度增加了40% |
|
1.3.0.0 | 修正上传的文件 |
|
1.2.0.0 | 删除了文件名应该有'的假设。xml的扩展 |
|
1.1.0.0 | 减少了处理大型XML文件的时间 |
启发:calciumImagingAnalysis (ciapkg),从谷歌地图下载海拔高度(需要API密钥),xml2struct,修复了bug并添加了特性,acampb311 / xml2struct,maxsich / loadSPE,显微镜图像浏览器(MIB),显微图像浏览器2 (MIB2),prowlpush:用于MATLAB的Prowl通知,写意前列腺注解,colladaParser,气象API连接器
完美!
好了!
不错的工作!
这是怎么回事的家伙!我注意到我们已经有了一些解决方案,为“内存不足”的错误如上所述。金宝搏官方网站好吧,我已经成功通过Python实现类似的代码步行解决这个问题。这可以帮助别人。下面的代码如下:
# # #进口填词
进口xml.etree。ElementTree在等
输入numpy为np
进口scipy。io是间谍
### xmltools类定义
类xmltools():
“‘
2020.04
@author: Laio Marinheiro
将xml数据结构组织为python dict(它是matlab的一个变量)
结构)。这在MATLAB xml2struct.m启发。
这也用途
“‘
def LoadXML(自我,xml_filename):
xml_tree = ET.parse (xml_filename)
xml_root = xml_tree.getroot()
返回xml_root
def ChildProp(自我、父母):
child_name =[] #每个子节点的名称
unique_child_names = []#孩子的唯一名称
child_len ={} #每个子节点的长度(每个子节点的子节点数)
child_idx = {}对父母孩子#指数
k = 0
对于父母中的孩子:
child_name.append (child.tag)
child_len[孩子。len(child) #不相关=/
child_idx[孩子。标记]= k
如果孩子。标签不在unique_child_names中:
unique_child_names.append (child.tag)
K = K + 1
在unique_child_names UNIQUE_NAME:
k = 1
for name in child_name:
如果name == unique_name:
child_len [UNIQUE_NAME] = K
K = K + 1
ChildProp = {}
ChildProp['名称')= child_name
ChildProp [' unique_names '] = unique_child_names
ChildProp[‘兰’]= child_len
ChildProp = child_idx“指数”
返回ChildProp
def GetDict(自我、父母):
Dict = {}
如果len(parent) == 0: # parent是最后一个字段
如果父母。文本不是没有:
Dict['文本']= parent.text
其他:
字典[“文本”] =“”#空字符串
如果父节点不是最后一个,那么它有子节点
childprop = toolbox.ChildProp(父)
如果len(父)== LEN(childprop [ '索引']):#儿童结构域
对于父母中的孩子:
字典[child.tag] = self.GetDict(子)
其他:#儿童是列表的元素(或清单)
unique_names =列表(childprop [ '索引']。键())
对于LIST_NAME在unique_names:#每个列表
字典[LIST_NAME] = np.zeros((childprop [ 'LEN'] [LIST_NAME],),D型细胞= np.object)
k = 0
对于父母中的孩子:
如果孩子。标签= = list_name:
Dict [list_name] [k] = self.GetDict(孩子)
K = K + 1
如果parent.attrib = {}!
Dict['属性']= parent.attrib
返回Dict类型
def Dict2Mat(自我、xml_filename字典):
spy.savemat (xml_filename[0: 4] +”。垫”,mdict = {pythonxml:词典})
高清xml2struct(个体经营,xml_filename):
xml_root = self.LoadXML (xml_filename)
xml_dict = {xml_root.tag: {}}
xml_dict [xml_root。标记]= self.GetDict (xml_root)
self.Dict2Mat(xml_filename,xml_dict)
# # #的例子
工具箱= xmltools ()
xml_filename_str = ' your_filename.xml '
工具箱。xml2struct(xml_filename_str )
谢谢!
比mathworks函数更好!
它工作,很容易使用!
直接开箱工作。
谢谢你! !
做得好!谢谢
我在哪里可以找到xml2struct的输出文件
强大而准确的
我想知道是否有任何与此脚本等价的python ?
做得好!
谢谢!
伟大的东西!谢谢!
这个功能工作完美!非常非常感谢!
伟大的工作!谢谢
非常适合我,这应该是MATLAB的一部分
应该是MATLAB的一部分吗
工作得很好,很健壮。
干得好,谢谢!
超。做得好。
好了!正是我一直在寻找!
不错的功能。谢谢你!
好提交!
我的建议是删除第137、138和139行:
name = matlab.lang.makeValidName(名称);
这个Matlab函数将确保用下划线替换所有无效的Matlab名称。
很好,默认情况下应该包含在MATLAB中。
似乎运行得很好——只是想知道如何再次将结构保存为XML ?我在评论中找不到这一点。
对修改xml文件非常有用
这是一个非常有用的脚本,但是对于大型的xml来说很慢,xmlread只使用了总时间的1/10。
我的改进意见:
改变
如果(〜的isEmpty(regexprep(文本。(textflag), '[\ s]的*', '')))
来
如果~ (isspace(文本。(textflag)))
并得到因子2的整体加速(至少在我的测试用例中)
非常感谢!
非常感谢,干得好
谢谢你!
我必须做一些修改以使我的XML文件工作。我将把它们放在下面,但由于这是我第一次使用这种文件类型,因此可能会有所不同。
第95行,目前版本为2017年7月3日
孩子。(名)=文本;
如果最后一个要解析的节点是一个注释(即它只包含一个字符串),那么它将覆盖所有存储了数据的子节点。其他节点包含以字符串值形式保存的数值。这是我的解决办法:
如果isfield(文本、文本)
。儿童(名称)= str2num(text.Text);
其他的
孩子。(名字)。(“评论”)= text.Comment;
结束
总体来说非常有帮助,是我需要什么,我把置换线后。
谢谢!
太好了! !非常感谢!!
这是一个非常有用的脚本!我用它来读取AUTOSAR XML文件!在阅读AR-XML文件时,我发现了两个难题:
1.{'-'|':'|'的长替换文本。'}在xml标记中导致了这样一个问题,即matlab字段名将超过63个字符!我把它们简化为{'_'|'c'|'d'}!帮助!
2.对于XML注释在xml文件中使用脚本失败!我解决了这个问题!看看吧!
函数内部:parseChildNodes(…)
% CDz 2016-12-21由于问题注释掉
% xml注释
%如果(~ isempty(字段名(文本)))
% children.(name){index} =文本;
%结束
% CDz 2016-12-21增加处理XML注释
如果(~ isempty(文本)& & isstruct(文本)
如果发现(strcmp(字段名(文本),“文本”))
孩子。(名字){指数}。('文本')= text.Text;
elseif找到(strcmp(字段名(文本),“评论”))
孩子。(名字){指数}。(“评论”)= text.Comment;
结束
结束
和
%CDZ 2016年12月21日注释掉由于与问题
% xml注释
% if(~isempty(文本)&& ~isempty(字段名(文本)))
%的儿童(名称)=文本。
%结束
% CDz 2016-12-21增加处理XML注释
如果(~ isempty(文本)& & isstruct(文本)
如果发现(strcmp(字段名(文本),“文本”))
孩子。(名字)。('文本')= text.Text;
elseif找到(strcmp(字段名(文本),“评论”))
孩子。(名字)。(“评论”)= text.Comment;
结束
结束
@ Wouter Falkena:如果你感兴趣,我可以提供这个文件的完整副本,你可以更新这个脚本
做得好
简单而实用。非常方便。
我是一个博士生,我需要在我的代码上应用这个函数来获得XML文件的属性
工作好了!尝试过xml_toolbox,但它从2014年起就坏了。这是一个可靠的替代品。
请我需要编辑一个xml文件
我已经查看了问题,实现了修复,增加了一些新的功能到脚本,并上传在这里://www.tatmou.com/matlabcentral/fileexchange/58700-xml2struct。另外,请尝试我的更新版本,让我知道如果现在工作得更好。
尼尔的方法对我不起作用……
不工作的框右出。斯特凡的修复的伟大工程!
关于注释和标题,还有和Sebastien一样的问题。
我收到了一个“java.lang”。OutOfMemoryError:超过GC开销限制”当试图打开一个汉字字典文件时http://www.edrdg.org/kanjidic/kanjidic2.xml.gz
这很好,但是对于大型xml文件来说太慢了。
丹尼尔
您可以更新的代码?我有同样的问题。
感谢这个非常灵活的脚本!最佳!
这正是我想要的。
谢谢Wouter,
它不完全,但感谢您的答复。该probem现在就解决了。如果有人有同样的问题我可以上传的代码。
你好,
发现一个bug:当同一节点中有文本和子节点时,文本会覆盖子节点。
解决办法:
取代
如果(~ isempty(字段名(文本)))
儿童(名称){索引} =文本。
结束
由:
如果isstruct(文本)
盛名=字段名(文本)
孩子。(名字){指数}。(盛名{1})=文本。(盛名{1});
结束
结束
也和替换:
如果(~ isempty(文本)& & ~ isempty(字段名(文本)))
孩子。(名)=文本;
结束
由:
如果isstruct(文本)
盛名=字段名(文本)
孩子。(名字)。(盛名{1})=文本。(盛名{1});
结束
结束
谢谢。
简单使用和工作伟大!!谢谢分享。
运行较大的xml需要很长时间。代码中有任何地方我可以至少向用户报告进度的waitbar吗?我尝试了两个for循环,但这似乎不是瓶颈。
非常简单的使用和它的工作。
“Andrew Wilson: Neill Weiss在之前的评论中给出的修正似乎解决了这个问题,所以如果能在更新中加入这个内容,那就太好了!
在大多数情况下工作得很好,但是当注释出现在层次结构的同一级别时,节点丢失的问题非常令人沮丧。尼尔·维斯在早些时候的评论/评论中给出的修正似乎解决了这个问题,所以如果能在更新中看到这一点,那就太好了!
似乎工作得很好,除了Sebastien Roy在09/10/14报道的——xml注释不起作用(导致其他数据丢失)
今天晚上下载了这个文件来处理一些XML数据。工作得很好。
对不起,贴错了行。
第154行为我解决了这个问题:
文本。(textflag) = char (getTextContent (theNode));
伟大的东西。
关于“未定义函数'toCharArray'输入参数类型为'double'。”Error:
对我来说,把154行改成
文本。(textflag) = char (getData (theNode));
因为已经在xml2struct的早期版本(在评论中的代码行中提及的153)
与直接使用xmlread相比,节省了大量时间。但是,当存在文本时,子节点有一个bug。子节点内容将被设置为文本,子节点的所有其他内容将丢失。作为文本处理的注释将导致同样的问题。试图读取这个xml将不会提供预期的结果:
< ?xml version = " 1.0 " encoding = " utf - 8 " ? >
<根>
<! - 应该是一个良性的评论 - >
< mystuff >有价值的数据< / mystuff >
根> < /
XML文件中的一些属性在开头有下划线,这是错误的,因为不允许字段名。简单的strrep解决了这个问题。
太棒了!
优秀的
停止使用XML,使用json.org/java[1]静态XML.toJSONObject()方法[2],在我的dropbox[3]中有一个预编译的jar文件,或者使用牛顿国王的JSON。NET[4]已经被他预编译,可以从codeplex[5]下载解压,然后在你的机器上使用。NET框架的版本。XML和JSON之间的转换在文档[6]和本文[7]中有描述。有关在MATLAB中使用Java[8]或。net[9]的更多信息,请参阅MATLAB文档。这是超级简单!
[1]http://json.org/java/
[2](http://json.org/javadoc/org/json/XML.html toJSONObject(以))
[3]https://dl.dropboxusercontent.com/u/19049582/JSON.jar
[4]http://james.newtonking.com/pages/json-net.aspx
[5]https://json.codeplex.com/
[6]http://james.newtonking.com/projects/json/help/index.html?topic=html/ConvertingJSONandXML.htm
[7]http://stackoverflow.com/a/814027/1020470
[8]//www.tatmou.com/help/matlab/using-java-libraries-in-matlab.html
[9]//www.tatmou.com/help/matlab/using-net-libraries-in-matlab.html
我看到一些其他用户报告这个问题,但无法找到如何解决这个问题:
未定义函数'toCharArray'输入参数类型为'double'。
任何想法?
问候
工作得很好。
没有完全测试空字段的情况,像一些评论者,但我得到了一个很好的结构,从我的输入文件。
我很失望,Matlab中没有内置类似的功能。仅xmlread和xmlwrite在访问和/或更新xml数据时就非常麻烦。
你好,
谢谢你的文件,它工作得很好。
但我也遇到了与Erik相同的问题,即数据字段为空。有人知道怎么解决这个问题吗?
建议比xml_read更快!
谢谢你的文件,但我有一个问题与空数据字段。
如果我有一个100x50的XML数据集,我可以很容易地导入到Excel中。然而,有几个字段是空的。例如,在(5,35:40)处,XML数据是空的。
当我使用xml2struct并尝试以相同的格式(100x50)创建一个单元格数组时,第5行中的数据在40:50之间转移到35:45位置,并从45:50保留了5个空格,因此数据没有对齐。
您知道如何处理空字段以保持它们在原始文件中的位置吗?
谢谢!
我只是想知道是否有人能确认一下我所做的是正确的。当我想把xml转换成matlab数组时,输入:
data=xml2struct('我要转换的文件名称');吗?这是所有吗?
我们遇到了Raoul Herzog报告的相同问题:对于输入参数类型为double的未定义函数或方法'toCharArray'。有解决办法吗?
对于评论的bug,@ Sirius3,我改变了下面的代码块来自:
如果(~ strcmp(名称、“#文本”)& & ~比较字符串(名称、“#评论”)& & ~比较字符串(名字,' # cdata_dash_section '))
%XML允许多次定义相同的元素,
%将它们分别放入不同的单元格中
如果(isfield(孩子的名字))
如果(~ iscell(孩子。(名字)))
%将存在元素转换为单元格格式
孩子。(名字)={孩子。(名)};
结束
指数=长度(孩子。(名字))+ 1;
%添加新的元素
孩子。(名字){指数}=蔡尔兹;
如果(~ isempty(字段名(文本)))
儿童(名称){索引} =文本。
结束
如果(~ isempty (attr))
孩子。(名字){指数}。(“属性”)= attr;
结束
其他的
%向结构中添加以前未知的(新)元素
孩子。(名)=蔡尔兹;
如果(~ isempty(文本)& & ~ isempty(字段名(文本)))
孩子。(名)=文本;
结束
如果(~ isempty (attr))
孩子。(名字)。(“属性”)= attr;
结束
结束
其他的
来
如果(~ strcmp(名称、“#文本”)& & ~比较字符串(名称、“#评论”)& & ~比较字符串(名字,' # cdata_dash_section '))
%XML允许多次定义相同的元素,
%将它们分别放入不同的单元格中
如果(isfield(孩子的名字))
如果(~ iscell(孩子。(名字)))
%将存在元素转换为单元格格式
孩子。(名字)={孩子。(名)};
结束
指数=长度(孩子。(名字))+ 1;
%添加新的元素
孩子。(名字){指数}=蔡尔兹;
textFieldNames =字段名(文本);
t = 1:length(textFieldNames)
textFieldName = textFieldNames {t};
孩子。(名字){指数}。(textFieldName) =文本。(textFieldName);
结束
如果(~ isempty (attr))
孩子。(名字){指数}。(“属性”)= attr;
结束
其他的
%向结构中添加以前未知的(新)元素
孩子。(名)=蔡尔兹;
如果(~ isempty(文本)& & ~ isempty(字段名(文本)))
textFieldNames =字段名(文本);
numTextFieldNames =长度(textFieldNames);
for i = 1:numTextFieldNames
thisFieldName = textFieldNames {};
孩子。(名字)。(thisFieldName) =文本。(thisFieldName);
结束
结束
如果(~ isempty (attr))
孩子。(名字)。(“属性”)= attr;
结束
结束
其他的
现在,当注释被解析时,child .(name)属性不会被吹走。
错误:当子节点之间有注释时,子节点会丢失。(第95行)
首先感谢出色的代码。
我有一个“小”问题根据细胞。在代码中,如果有多于一个子单元格,则创建一个单元格,否则不创建。即使节点只有一个子节点,我也要创建一个单元格(只有一个元素)
对我来说很有效。非常感谢。
xml2struct似乎有一个bug:
如果需要,我可以提供相应的xml文件给你。
???未定义函数或方法'toCharArray',用于输入参数类型为'double'。
在==> xml2struct>parseAttributes在174时出错
str = toCharArray (toString(项目(theAttributes,把1)))';
错误在==> xml2struct>getNodeData在141
ATTR = parseAttributes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct>getNodeData在147处出错
[儿童的,文本,textflag] = parseChildNodes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct>getNodeData在147处出错
[儿童的,文本,textflag] = parseChildNodes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct>getNodeData在147处出错
[儿童的,文本,textflag] = parseChildNodes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct>getNodeData在147处出错
[儿童的,文本,textflag] = parseChildNodes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct>getNodeData在147处出错
[儿童的,文本,textflag] = parseChildNodes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct>getNodeData在147处出错
[儿童的,文本,textflag] = parseChildNodes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct>getNodeData在147处出错
[儿童的,文本,textflag] = parseChildNodes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct>getNodeData在147处出错
[儿童的,文本,textflag] = parseChildNodes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct>getNodeData在147处出错
[儿童的,文本,textflag] = parseChildNodes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct>getNodeData在147处出错
[儿童的,文本,textflag] = parseChildNodes(theNode);
误差在==> xml2struct> parseChildNodes在72
[文本,名称,ATTR,童车,textflag] = getNodeData(theChild);
在==> xml2struct的57处出错
s = parseChildNodes (xDoc);
我个人遇到的一个问题是xml2struct不能处理CDATA块。
可以很容易地固定,将第67行替换为:
如果(~ strcmp(名称、“#文本”)& & ~比较字符串(名称、“#评论”)& & ~比较字符串(名字,' # cdata_dash_section '))
第94行:
/ / / / / / / / / / / / /
其他方面也很好,谢谢。
优秀的!我拉我的头发,从XML文件,有了这个,我读到的数字在一分钟内做到了
非常适合小文件。我测试了一些较大的>100000条目的文件,这大约需要178秒。
感谢您对这个建议沃纳先生。我已经更新了文件,它是目前正在由MATLAB中心审查。很快就会显示在这里。
谢谢你的工作。
您可能希望通过以下替换线152-154加快约40%解析属性:
STR = theAttributes.item(计数1).toString.toCharArray()';
k = strfind (str, ' = ');
attr_name = regexprep (str (1: (k (1) 1)), [-:], ' _ ');
属性。(attr_name) = str (k (1) + (2): (end-1));
谢谢,您的自动字段命名系统在处理XML文件解析出的数据时非常好用。
谢谢!我终于跨过一个工具,可以提取从ISO19115 / 19139 xml文件信息来了。
简单,工作得很好!这些结构有点冗长但它们应该能被我的程序解析;任何试图折叠某些嵌套结构的尝试只会降低代码的速度(一些类似的提交会这样做,但速度要慢得多)。谢谢!
诉感谢!我用它来读取Collada文件(几何文件谷歌草图)。工作就像一个魅力!
你是对的。我已经删除了“的.xml”扩展名的假设,除非该文件无法找到。更新文件目前正在审查通过MATLAB中心,应该很快就会出现在这里。
警告:所有的XML文件都没有“的.xml”扩展
曾在第一次尝试加载的OSM数据文件。
在找到这个例程之前,我一直在绞尽脑汁地试图找出如何自动访问.xml文件中的一小段数据。