2012-10-02 26 views
5

Bir XML'i Groovy ve Java ScriptEngine API'sini kullanarak ayrıştırmaya çalışıyorum. Aşağıdaki kod tam olarak bunu yapar ama aynı şeyi yapmanın daha iyi bir yolu olup olmadığını öğrenmek istedim. Ve ayrıca bununla ilgili herhangi bir performans etkisi varsa?Groovy yoluyla Java'da XML ayrıştırma

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; 
    } 
} 

Çıktı:

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

thankx çok Rob! – Arham

cevap

6

...

Bu aynı şeyi yapar: Aslında

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

, JVM komut dosyası altyapısı yerine GroovyShell kullanabilirsiniz ve tha t onu aşağı indirir:

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

harika ... teşekkürler Tim. – Arham

+0

@Arham GroovyShell :-) ile bunu yapmanın başka bir yolu eklendi –

+0

Teşekkürler Tim, bir problemi çözmenin çok az ayrıntıyla karşılaştığını görmek gerçekten harika. ScriptEngine'ı kullanmanın daha başka bir yolunu daha ekledim. – Arham

4

ScritpEngine daha fazla ölçülebilir hale getirmek için, biz Derlenebilir arayüzünü kullanabilirsiniz. Aşağıdaki kod, Tim'in yorumları ve here numaralı tartışmanın bir karışımıdır.

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; 
} 

Çıktı: Sizin Groovy komut "groovy-er" olabilir

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