2

我正在尝试提出一种算法,该算法允许我将 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>

我有解析器给我这些值,所以我可以访问这些数据。到目前为止,我的想法是使用反射 JavaAPI 来完成这项肮脏的工作,否则我几乎必须创建一个符号表来完成我想要的。我知道我可以使用ReflectionAPI 来查找符号:

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>

此外,如果使用methodor时可能会出现class一种潜在的并发症object,因此应该有某种递归方法来产生正确的结果。我对ReflectionAPI 完全陌生,所以我想知道是否有人比我更了解如何做到这一点。谢谢

*更新 我确实可以访问这些类,并且我可以实例化它们,但是,我需要找出正确的参数,所以这是一项更复杂的任务。

4

2 回答 2

1

您的问题不清楚:您是否有存储数据的类,或者没有?如果您还没有表示数据的类,并且不想创建它们,那么反射对您没有帮助。

相反,我建议只使用JAXP来生成输出。创建一个Document,向其添加Element子级,然后使用序列化程序生成输出。谷歌“DOM 教程”可以找到一些例子。

于 2012-08-29T13:28:52.150 回答
0

我创建了示例应用程序只是为了为以下类创建结构

class Rate
{
private double minValue;

public Rate withValue(double value)
{
    minValue = value;
    return this;
}

public double getValue()
{
    return minValue;
}
}

以下类Rate使用创建Reflection然后调用withValueAPI

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());

        }

    }
}
}
于 2012-08-29T13:56:29.173 回答