简单框架xml反序列化 - 查找属性的存在

时间:2013-01-12 21:45:20

标签: java xml-deserialization simple-framework

是否有可能在java的Simple框架中查找指定属性的存在? 假设我有以下xml:

<packet id="250">
  <msg id="1" uniqueAttribute1="some value" x="7" />
  <msg id="2" someStuff="123" />
  <msg id="3" someOtherStuff="abc" />
</packet>

上面的所有消息都应该被反序列化为可能从公共基类继承的不同类的对象。哪个msg应该实例化哪个类的对象应该依赖于属性的名称。意思是如果在msg中存在名为'uniqueAttribute'的属性,那么应该创建类Foo的对象,如果'someStuff'是类Bar的对象,依此类推。

我想到的唯一方法是尝试反序列化类的对象并捕获异常并重试哪些听起来很糟糕。

如果“简单”框架不可能,你可以建议一些其他的方法吗?

2 个答案:

答案 0 :(得分:1)

我没有看到需要一个具有这样一个基本要求的框架,但是我可能不会完全理解你的需求。我最初会从像SAX解析处理程序这样简单的东西开始。完全手工编码和未经测试,但基本想法见这里:

import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

class XmlHandler extends DefaultHandler {
    Map msgClasses = new HashMap(){{ put("uniqueAttribute1", "Foo"); put("someStuff", "Bar"); }};

    public MessageBase messageFromAttributes(final org.xml.sax.Attributes attributes) {
        for(int i=0; i<attributes.getLength(); i++) {
            if(msgClasses.contains(attributes.getValue(i))) {
                try{
                    Class msgClass = Class.forName(attributes.getValue(i));
                    return msgClass.newInstance();
                } catch(ClassNotFoundException e) {
                    return null;
                }
            }
        }
    }

    @Override
    public final void startElement(String uri, String localName, String name,
            final org.xml.sax.Attributes attributes) throws SAXException {
        if (localName.equals("msg")) {
            MessageBase message = messageFromAttributes(attributes);
        }
    }

    @Override
    public final void endElement(String uri, String localName, String name) throws SAXException {

        if (localName.equals("msg")) {
        }
    }

}

上面示例的想法是将类名映射到特定属性,然后在处理SAX解析事件实例化时,找到映射中应指向正确类名的任何给定属性。此时,您可以使用反射实例化该类并继续。如有必要,您可以选择使用剩余的attibute值填充类。

答案 1 :(得分:1)

有很多方法可以做到这一点。通常可以使用访客或策略。有关如何使用访客的信息,请参阅以下内容。这使用命名空间来确定类型,但您可以将其更改为使用属性或其中的一些属性。

https://simple.svn.sourceforge.net/svnroot/simple/trunk/download/stream/src/test/java/org/simpleframework/xml/strategy/ClassToNamespaceVisitor.java

此外,您可以使用转换器执行此操作。看一下教程。