0

是否可以在 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>

上面所有的 msgs 都应该被反序列化为不同类的对象,可能是从一个公共基类继承的。哪个 msg 应该实例化哪个类的对象应该取决于属性的名称。这意味着如果在 msg 中存在名为“uniqueAttribute”的属性,则应创建 Foo 类的对象,如果存在“someStuff”类 Bar 的对象,依此类推。

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

如果“简单”框架无法实现,也许您可​​以建议其他方法?

4

2 回答 2

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 解析事件时实例化查找映射中应该指向正确类名的任何给定属性。此时,您可以使用反射实例化该类并继续。如有必要,您可以选择使用剩余的属性值填充类。

于 2013-01-14T16:06:34.633 回答
1

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

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

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

于 2013-01-15T08:03:32.727 回答