如何让Matlab读取正确数量的xml节点

时间:2012-07-18 19:09:30

标签: matlab xml-parsing

我正在使用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

2 个答案:

答案 0 :(得分:10)

幕后的XML解析器正在为节点元素之间的所有空格创建#text节点。无论是换行还是缩进,它都会创建一个带有换行符的#text节点,并在节点的数据部分中跟随缩进空格。因此,在解析“ref”元素的子节点时提供的xml示例中,它返回5个节点

  1. 节点1:带有换行符和缩进空格的#text
  2. 节点2:“请求者”节点,该节点又在数据部分中有一个带有“John Doe”的#text子节点
  3. 节点3:带有换行符和缩进空格的#text
  4. 节点4:“项目”节点,该节点又在数据部分中有一个带有“X”的#text子项
  5. 节点5:带有换行符和缩进空格的#text
  6. 此函数会为您删除所有这些无用的#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);