2012-02-28 88 views
7

我需要用MATLAB解析XML字符串(注意:没有文件I/O,所以我不想将字符串写入文件然后读取它们)。我从HTTP连接接收字符串,解析应该非常快。我主要关心的是读取整个字符串中某些标记的值解析MATLAB中的XML字符串

网络充满了关于使用regexp解析XML的死亡威胁,所以我不想进入这个过程。我知道MATLAB有无缝的Java集成,但我不是很懂Java的人。有没有一种快速的方法可以非常快速地从XML获取特定值?

例如,我想从下面的字符串中获取'volume'信息并将其写入一个变量。

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 


<root> 
    <volume>256</volume> 
    <length>0</length> 
    <time>0</time> 
    <state>stop</state> 
    .... 
+0

您使用的是Windows吗?如果是这样,那么我可以为您提供一个.NET解决方案。 – 2012-02-28 22:42:43

回答

1

有一个完整的class of functions用于处理XML处理,包括xmlreadxmlwrite。这些应该对你的问题非常有用。

+2

但他明确表示他不想处理文件 – 2012-02-28 22:42:10

7

对于它的价值,下面是Matlab的可执行Java代码来执行所需的任务,而无需编写到中间文件:

%An XML formatted string 
strXml = [... 
    '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>' char(10)... 
    '<root>' char(10) ... 
    ' <volume>256</volume>' char(10) ... 
    ' <length>0</length>' char(10) ... 
    ' <time>0</time>' char(10) ... 
    ' <state>stop</state>' char(10) ... 
    '</root>' ]; 

%"simple" java code to create a document from said string 
xmlDocument = javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder.parse(java.io.StringBufferInputStream(strXml)); 

%"intuitive" methods to explore the xmlDocument 
nodeList = xmlDocument.getElementsByTagName('volume'); 
numberOfNodes = nodeList.getLength(); 

firstNode = nodeList.item(0); 
firstNodeContent = firstNode.getTextContent; 

disp(firstNodeContent); %Returns '256' 

作为替代方案,如果您的应用程序允许的话,考虑将URL直接传递到您的XML解析器中。未经测试的java代码如下,但也可能打开Matlab内置的xslt函数。

xmlDocument = javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder.parse('URL_AS_A_STRING_HERE'); 

文档here。从“javax.xml.parsers”包开始。

1

我对Matlab的API根本不熟悉,但我会指出,如果您只想从您正在重新获取的XML流中取出特定值,那么使用Pursuit概述的DOM方法将占用大部分时间/内存HTTP连接。

尽管STAX会为您提供Java中最快的解析方法,但使用API​​可能会很笨拙,特别是如果您不熟悉Java。你可以使用SJXP,它是Java中STAX解析的一个非常薄弱的​​抽象(免责声明:我是作者),它允许你定义你想要的元素的路径,然后给解析器一个流(在这种情况下你的HTTP流),它会为你抽出所有的值。

举个例子,假设您想要到/ root /州和/根/音量值超出您发布的示例XML的,实际的Java将是这个样子:

// Create /root/state rule 
IRule stateRule = new DefaultRule(Type.CHARACTER, "/root/state") { 
    @Override 
    public void handleParsedCharacters(XMLParser parser, String text, Object userObject) { 
     System.out.println("State is: " + text); 
    } 
} 

// Create /root/volume rule 
IRule volRule = new DefaultRule(Type.CHARACTER, "/state/volume") { 
    @Override 
    public void handleParsedCharacters(XMLParser parser, String text, Object userObject) { 
     System.out.println("Volume is: " + text); 
    } 
} 

// Create the parser with the given rules 
XMLParser parser = new XMLParser(stateRule, volRule); 

你可以做所有的程序初始化在某个时候再启动后,当您从HTTP连接中的数据流,你会做这样的事情:

parser.parser(httpConnection.getOutputStream()); 

等;那么您的规则中定义的所有处理程序代码将在解析器通过HTTP连接中的字符流运行时被调用。

正如我所提到的,我并不熟悉Matlab,也不知道“Matlab-i-fy”这个代码的正确方法,但它看起来像第一个例子,你可以或多或少地使用Java API直接在这种情况下,如果这个解决方案比DOM方法重要的话,这个解决方案将更快并且使用更少的内存来解析。