基于Groovy的Java中XML解析

基于Groovy的Java中XML解析,java,xml,groovy,Java,Xml,Groovy,我正在尝试使用Groovy和Java的ScriptEngineAPI解析XML。 下面的代码正是这样做的,但我想知道是否有更好的方法可以做到这一点。还有,是否有任何与此相关的性能影响 import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.scr

我正在尝试使用Groovy和Java的ScriptEngineAPI解析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;
/*
<books>
    <book id="1">
        <name>"Catcher In the Rye"</name>
        <author>J.D. Salinger</author>
    </book>
    <book id="2">
      <name>"KiteRunner"</name>
      <author>Khaled Hosseini</author>
    </book>
</books>
*/

public class XMLParsing{
  public static void main(String[] args) {
    Map<String, ArrayList<String>> resultMap 
                                     = new HashMap<String, ArrayList<String>>();
    resultMap = getBookDetails("c:\\temp\\book.xml");
    System.out.println(resultMap);
  }


  public static Map<String ArrayList<String>> getBookDetails(String scriptXml) {
    Map<String, ArrayList<String>> resultMap = 
                                       new HashMap<String, ArrayList<String>>();
    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<String>>)  
                  inv.invokeFunction("getBookInformation", params);
    } catch (ScriptException e) {
      e.printStackTrace();
    } catch (NoSuchMethodException e) {
      e.printStackTrace();
    }
    return resultMap;
  }
}

为了使ScriptEngine更具性能,我们可以使用可编译接口。下面的代码混合了Tim的评论和讨论中的新奇之处


您的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<String, ArrayList<String>> resultMap = getBookDetails("test.xml");
    System.out.println(resultMap);
  }

  public static Map<String, ArrayList<String>> 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<String, ArrayList<String>>)ret ;
  }
}
import java.util.ArrayList;
导入java.util.Map;
导入groovy.lang.Binding;
导入groovy.lang.GroovyShell;
公共类XML解析{
公共静态void main(字符串[]args){
Map resultMap=getBookDetails(“test.xml”);
系统输出打印项次(结果映射);
}
公共静态映射getBookDetails(字符串scriptXml){
绑定b=新绑定();
b、 setVariable(“xmlFile”,scriptXml);
GroovyShell外壳=新的GroovyShell(b);
Object ret=shell.evaluate(“new-XmlSlurper().parse(xmlFile.book.findAll().collectEntries{[(it@id):[it.name,it.author]]);
返回(Map)ret;
}
}

@Arham添加了另一种使用GroovyShell的方法:-)谢谢Tim,看到这么多用最少的冗长来解决问题的方法真是太好了。我添加了另一种更高效的使用ScriptEngine的方法。
{1=["Catcher In the Rye", J.D. Salinger], 2=["KiteRunner", Khaled Hosseini]}
  String fact = "def getBookInformation(n) {" +
                "  xmlDesc = new XmlSlurper().parse(n)\n" +
                "  xmlDesc.book.findAll().collectEntries {\n"+
                "    [ (it.@id):[ it.name, it.author ] ]\n" +
                "  }\n" +
                "}" ; 
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<String, ArrayList<String>> resultMap = getBookDetails("test.xml");
    System.out.println(resultMap);
  }

  public static Map<String, ArrayList<String>> 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<String, ArrayList<String>>)ret ;
  }
}