我正在尝试使用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;
/*
<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;
}
}
输出:
{1=["Catcher In the Rye", J.D. 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<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 ;
}
}
问题内容: 我需要转换具有嵌套(分层)结构形式的大型XML文件 变成更扁平(“切碎”)的形式,每个重复的嵌套块有1个块。 数据具有许多不同的标签和层次结构变化(尤其是在层次XML之前和之后的切碎XML的标签数量),因此,理想情况下,不应对标签和属性名称或层次级别进行任何假设。 仅4个级别的层次结构的顶层视图看起来像 然后所需的输出将是 也就是说,如果在每个级别上都有不同的组件,那么将产生总共不同的
问题内容: 由于Java不支持指针,如何像在C和C ++中那样通过Java引用来调用函数? 问题答案: 在Java中,真正的按引用传递是不可能的。Java通过值传递所有内容,包括引用。但是您可以使用容器对象来模拟它。 使用以下任何一个作为方法参数: 数组 集合 AtomicXYZ类 并且,如果您在方法中更改其内容,则更改的内容将可用于调用上下文。 糟糕,您的意思显然是通过引用调用方法。在Java中
问题内容: 有人可以帮我为什么下面的代码不起作用吗?我正在Xcode.1 Playground中对其进行测试 问题答案: 操场是沙盒,因此您将无法仅从用户文件夹中的任何位置抓取文件。以下是将该文件添加到游乐场以使其可访问的方法: 在Finder中找到您的“ .playground”文件 右键单击并选择“显示包装内容” 您应该看到“ timeline.xctimeline”,“ contents.x
问题内容: 我正在编写一个处理具有深节点结构的xml文件(> 1000)的应用程序。使用woodstox(事件API)大约需要6秒钟来解析具有22.000个节点的文件。 该算法被置于与用户交互的过程中,其中只有几秒钟的响应时间是可以接受的。因此,我需要改进如何处理xml文件的策略。 我的过程分析xml文件(仅提取几个节点)。 处理提取的节点,并将新结果写入新的数据流(产生具有修改后的节点的文档副本
问题内容: 我正在开发客户端-服务器软件,其中客户端按如下方式连接到数据库服务器。 这两个应用程序始终位于同一本地网络上。我的问题是本地网络使用代理时,在这种情况下,MySQL连接失败。 当本地网络上的代理服务器时,如何与Java编程语言(MySQL数据库)建立连接? 谢谢您的帮助。问候! 问题答案: 尝试使用和系统属性。看看这里的一章“2.4)SOCKS”和这里。(http.proxyHost不
问题内容: 我需要取消转义包含转义的XML标签的xml字符串: 我确实找到了一些可以执行此任务的库,但是我宁愿使用可以执行此任务的单一方法。 有人可以帮忙吗? 干杯,Bas Hendriks 问题答案: (commons-lang,下载)