我正在尝试提出一种算法,它允许我将Java类编组为XML而不创建该类的对象(这是问题所在,而且我使用的工具非常复杂)。我必须从日志文件中读取数据并将其转换为XML文件。 日志文件中的示例:
2206:org.powertac.common.RandomSeed::4::init::TariffMarket::0::fees::-6239716112490883981
2213:org.powertac.common.msg.BrokerAccept::null::new::1
2214:org.powertac.common.msg.BrokerAccept::null::new::1::null
2216:org.powertac.common.RandomSeed::5::init::org.powertac.du.DefaultBrokerService::0::pricing::8741252857248937781
2226:org.powertac.common.TariffSpecification::6::new::1::CONSUMPTION
2231:org.powertac.common.Rate::7::new
2231:org.powertac.common.Rate::7::withValue::-0.5
2232:org.powertac.common.Rate::7::setTariffId::6
日志文件的模式是:
<id>:<class_name>::<order_of_execution>::<method_or_new>::<arguments>
因此,我想将以下一行翻译成XML
:
2231:org.powertac.common.Rate::7::new
将写成:
<org.powertac.common.Rate>
<rate>0</rate>
</org.powertac.common.Rate>
我有解析器给我值,所以我可以访问这些数据。我到目前为止的想法是为我使用Reflection Java
API来处理脏工作,否则我必须创建一个符号表来完成我想要的工作。我知道我可以使用Reflection
API来查找符号:
private static void printMembers(Member[] mbrs, String s) {
out.format("%s:%n", s);
for (Member mbr : mbrs) {
if (mbr instanceof Field)
out.format(" %s%n", ((Field)mbr).toGenericString());
else if (mbr instanceof Constructor)
out.format(" %s%n", ((Constructor)mbr).toGenericString());
else if (mbr instanceof Method)
out.format(" %s%n", ((Method)mbr).toGenericString());
}
if (mbrs.length == 0)
out.format(" -- No %s --%n", s);
out.format("%n");
}
我想要完成的一个例子是:
2231:org.powertac.common.Rate::7::withValue::-0.5
然后我会使用class
名称org.powertac.common.Rate
,使用Class
:
Class<?> c = Class.forName(args[0]);
printMembers(c.getMethods(), "Methods");
返回方法withValue
及其参数,因此我可以通过编程方式创建以下XML
代码:
<org.powertac.common.Rate>
<withValue>-0.5</withValue>
</org.powertac.common.Rate>
此外,如果method
或class
以object
为例,那么可能存在一个潜在的复杂因素,因此应该采用某种递归方法来产生正确的结果。
我对Reflection
API完全不满意,所以我想知道是否有人比我更了解如何实现这一目标。
感谢
*的 更新 我可以访问类,我可以实例化它们,但是,我需要找出正确的参数,所以这是一个更复杂的任务。
答案 0 :(得分:1)
您的问题不明确:您是否有用于存储数据的课程,或者不是吗?如果您还没有代表数据的类,并且不想创建它们,那么反射对您没有帮助。
相反,我建议只使用JAXP来生成输出。创建一个Document
,向其中添加Element
子项,然后使用序列化程序生成输出。谷歌为“DOM教程”找到了一些例子。
答案 1 :(得分:0)
我创建了示例应用程序,只是为了创建后续类
的结构class Rate
{
private double minValue;
public Rate withValue(double value)
{
minValue = value;
return this;
}
public double getValue()
{
return minValue;
}
}
以下课程使用Rate
创建Reflection
,然后致电withValue
API
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
public class Test
{
public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException, InstantiationException
{
Class<?> class1 = Class.forName("Rate");
Object obj = class1.newInstance();
for (Method m : class1.getMethods())
{
if (m.getName().equals("withValue"))
{
Class<?>[] parameterTypes = m.getParameterTypes();
System.out.println(Arrays.toString(m.getParameterTypes()));
Object methodArgs[] = new Object[parameterTypes.length];
for (Class<?> parameterType : parameterTypes)
{
// Here I know there is primitive and double but your logic
// should check for each and every type
if (parameterType == Double.TYPE)
{
double value = 0.5;// Value to be passed
// directly using 0 since I know only element is there
methodArgs[0] = value;
}
}
// Now Creating Rate here directly to check but you may have to
// again cast to generic object
Rate rate = (Rate) m.invoke(obj, methodArgs);
System.out.println(rate.getValue());
}
}
}
}