2012-10-02 7 views
5

Ich versuche, ein XML mit Groovy und der ScriptEngine API von Java zu analysieren. Der Code unten tut genau das, aber ich wollte wissen, ob es bessere Möglichkeiten gibt, dasselbe zu tun. Und wenn es irgendwelche Auswirkungen auf die Leistung hat?XML Parsing in Java über Groovy

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 = [email protected];" 
       + 
       //"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; 
    } 
} 

Ausgang:

{1=["Catcher In the Rye", J.D. Salinger], 2=["KiteRunner", Khaled Hosseini]} 
+1

dankeschön viel Rob! – Arham

Antwort

6

Ihr Groovy Skript "groovy-er" ...

Dies macht das Gleiche sein könnte:

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

Tat Sie könnten die GroovyShell anstelle der JVM-Skript-Engine und Tha verwenden t bringt dich runter zu:

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 { [ ([email protected]):[ it.name, it.author ] ] }") ; 
    return (Map<String, ArrayList<String>>)ret ; 
    } 
} 
+0

genial ... danke Tim. – Arham

+0

@Arham Eine andere Möglichkeit, es mit GroovyShell zu machen :-) –

+0

Danke Tim, es ist wirklich großartig, so viele Varianten zu sehen, wie man ein Problem mit minimaler Ausführlichkeit lösen kann. Ich habe eine weitere performante Art der Verwendung von ScriptEngine hinzugefügt. – Arham

4

Um ScritpEngine performanter zu machen, könnten wir kompilierbare Schnittstelle verwenden. Der folgende Code ist eine Mischung aus Neuigkeiten aus Tims Kommentaren und der Diskussion here.

public static Map<String, ArrayList<String>> 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 { [ ([email protected]):[ it.name, it.author ] ] }");   
      return (Map<String, ArrayList<String>>)(script.eval()); 
     } 
    } catch (ScriptException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

Ausgang:

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