通过Groovy在Java中进行XML解析

我正在尝试使用Groovy和Java的ScriptEngine API来解析XML。 下面的代码完全是这样,但我想知道是否有更好的方法来做同样的事情。 还有与此相关的性能影响吗?

import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; /*   "Catcher In the Rye" JD Salinger   "KiteRunner" Khaled Hosseini   */ public class XMLParsing{ public static void main(String[] args) { Map<String, ArrayList> resultMap = new HashMap<String, ArrayList>(); resultMap = getBookDetails("c:\\temp\\book.xml"); System.out.println(resultMap); } public static Map<String ArrayList> getBookDetails(String scriptXml) { Map<String, ArrayList> resultMap = new HashMap<String, ArrayList>(); ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("groovy"); String fact = "import java.util.HashMap;" + "import java.util.ArrayList;" + "def getBookInformation(n){" + "def map1 = new HashMap();" + "xmlDesc = new XmlSlurper().parse(n);" + "xmlDesc.book.findAll{it}.each {" + "def list1 = new ArrayList();" + "def id = it.@id;" + //"println id;"+ "def name = it.name;" + "def author = it.author;" + "list1.add(name);" + "list1.add(author);" + "map1.put(id, list1);" + "};" + "return map1;}"; try { engine.eval(fact); Invocable inv = (Invocable) engine; Object[] params = {scriptXml}; resultMap = (Map<String,ArrayList>) inv.invokeFunction("getBookInformation", params); } catch (ScriptException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return resultMap; } } 

输出:

 {1=["Catcher In the Rye", JD Salinger], 2=["KiteRunner", Khaled Hosseini]} 

你的Groovy脚本可能是“groovy-er” ……

这也是做同样的事情:

  String fact = "def getBookInformation(n) {" + " xmlDesc = new XmlSlurper().parse(n)\n" + " xmlDesc.book.findAll().collectEntries {\n"+ " [ (it.@id):[ it.name, it.author ] ]\n" + " }\n" + "}" ; 

实际上,您可以使用GroovyShell而不是JVM脚本引擎,这可以帮助您:

 import java.util.ArrayList; import java.util.Map; import groovy.lang.Binding ; import groovy.lang.GroovyShell ; public class XMLParsing { public static void main(String[] args) { Map> resultMap = getBookDetails("test.xml"); System.out.println(resultMap); } public static Map> getBookDetails( String scriptXml ) { Binding b = new Binding() ; b.setVariable( "xmlFile", scriptXml ) ; GroovyShell shell = new GroovyShell( b ) ; Object ret = shell.evaluate( "new XmlSlurper().parse( xmlFile ).book.findAll().collectEntries { [ (it.@id):[ it.name, it.author ] ] }" ) ; return (Map>)ret ; } } 

为了使ScritpEngine更高效,我们可以使用Compilable接口。 下面的代码是蒂姆的评论和这里的讨论的新颖性。

 public static Map> getBookDetails(String scriptXml) { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("groovy"); engine.put("xmlFile", scriptXml); try { if (engine instanceof Compilable) { CompiledScript script = ((Compilable) engine).compile( "new XmlSlurper().parse( xmlFile ).book.findAll().collectEntries { [ (it.@id):[ it.name, it.author ] ] }" ); return (Map>)(script.eval()); } } catch (ScriptException e) { e.printStackTrace(); } return null; } 

输出:

 {1=["Catcher In the Rye", JD Salinger], 2=["KiteRunner", Khaled Hosseini]}