我正在使用matlab的xmlread内部函数读取一个简单的xml文件。
<root>
<ref>
<requestor>John Doe</requestor>
<project>X</project>
</ref>
</root>
但是当我调用ref
元素的getChildren()时,它告诉我它有 5 个孩子。
效果很好IF 我将所有XML都放在一行中。 Matlab告诉我ref
元素有 2 子元素。
它似乎不喜欢元素之间的空格。
即使我在oXygen XML编辑器中运行 Canonicalize ,我仍然会得到相同的结果。因为Canonicalize仍留有空间。
Matlab将java和xerces用于xml的东西。
我能做些什么才能保持我的xml文件采用人类可读的格式(不是全部在一行中),但仍然可以正确解析它?
filename='example01.xml';
docNode = xmlread(filename);
rootNode = docNode.getDocumentElement;
entries = rootNode.getChildNodes;
nEnt = entries.getLength
答案 0 :(得分:10)
幕后的XML解析器正在为节点元素之间的所有空格创建#text节点。无论是换行还是缩进,它都会创建一个带有换行符的#text节点,并在节点的数据部分中跟随缩进空格。因此,在解析“ref”元素的子节点时提供的xml示例中,它返回5个节点
此函数会为您删除所有这些无用的#text节点。请注意,如果你有意拥有一个只由空格组成的xml元素,那么这个函数将删除它,但对于99.99%的xml情况,这应该可以正常工作。
function removeIndentNodes( childNodes )
numNodes = childNodes.getLength;
remList = [];
for i = numNodes:-1:1
theChild = childNodes.item(i-1);
if (theChild.hasChildNodes)
removeIndentNodes(theChild.getChildNodes);
else
if ( theChild.getNodeType == theChild.TEXT_NODE && ...
~isempty(char(theChild.getData())) && ...
all(isspace(char(theChild.getData()))))
remList(end+1) = i-1; % java indexing
end
end
end
for i = 1:length(remList)
childNodes.removeChild(childNodes.item(remList(i)));
end
end
像这样称呼
tree = xmlread( xmlfile );
removeIndentNodes( tree.getChildNodes );
答案 1 :(得分:1)
我觉得@cholland的答案很好,但我不喜欢额外的xml工作。所以这里有一个从xml文件副本中去除空格的解决方案,这是不需要的元素的根本原因。
fid = fopen('tmpCopy.xml','wt');
str = regexprep(fileread(filename),'[\n\r]+',' ');
str = regexprep(str,'>[\s]*<','><');
fprintf(fid,'%s', str);
fclose(fid);