【问题标题】:demarshalling an xml where attributes determine type对属性确定类型的 xml 进行解组
【发布时间】:2014-07-03 21:15:56
【问题描述】:

我收到的是 xml 文档(我无法控制其格式)。我想知道是否可以根据元素属性 id 对这个 xml 进行解组。所以不同的对象类型将共享相同的元素名称。

另外,我正计划使用 Simile XML,因为我使用的是 Android,而 JAXB 不喜欢 Android。

所以我想要类似的东西:

class Root {
  Person p;
  Car c;
  ArrayList<Person> plist;
}

class Person{
  String name;
}

class Car {
  String type;
}

来自

<root>
  <object id="person">
    <name> bob </name>
  </object>
  <object id="car">
    <model> ford </ford>
  </object>
  <sequence id="personSequence">
    <object id="person">
      <name> bob </name>
    </object>
    <object id="person">
      <name> bob </name>
    </object>
  </sequence>
</root>

但是,我确信我收到的文档将始终保持相同的顺序,并具有相同数量的顶级元素。例如,

Rool 将始终拥有:1 人、1 辆汽车、1 人、2 辆汽车,以及一系列未知大小的汽车。

<root>
  <person />
  <car />
  <person />
  <car />
  <car />
  <sequence >
    I don't know how many objects will be in here
  <sequence >
<root>

非常感谢。

【问题讨论】:

    标签: java android xml marshalling simple-framework


    【解决方案1】:

    您可以使用Converter-实现来执行此操作。这允许您自己实现(反)序列化的过程。

    这里有一个建议

    • 作为所有对象(人、汽车等)基础的抽象类
    • 为那些实现
    • 包含所有其他元素的根对象
    • Converter 从节点创建具体的根对象

    顺便说一句。如果您使用转换器,则不必添加那些简单的注释 - 但是,这始终是一个好主意,以防万一您需要它们。

    (抽象)所有对象的基类:

    @Root()
    public abstract class ObjectElement
    {
        @Attribute(name = "id")
        private String id;
    
    
        public ObjectElement(String id)
        {
            this.id = id;
        }
    
        // ...
    }
    

    人物类:

    @Root(name = "object")
    public class PersonObject extends ObjectElement
    {
        @Element(name = "name")
        private String name;
    
    
        public PersonObject(String name)
        {
            super("person");
            this.name = name;
        }
    
        // ...
    }
    

    汽车类:

    @Root(name = "object")
    public class CarObject extends ObjectElement
    {
        @Element(name = "model")
        private String model;
    
    
        public CarObject( String model)
        {
            super("car");
            this.model = model;
        }
    
        // ...
    }
    

    序列类:

    @Root(name = "sequence")
    public class SequenceObject extends ObjectElement
    {
        @ElementList(inline = true)
        private final List<ObjectElement> elements;
    
    
        public SequenceObject()
        {
            super("personSequence");
            this.elements = new ArrayList<>();
        }
    
        // ...
    }
    

    root-元素;它有它的子元素(汽车等)的实例并映射&lt;root&gt; ... &lt;/root&gt; 元素。

    @Root(name = "root")
    @Convert(RootElementConverter.class) // Set Converter here!
    public class RootElement
    {
        private final List<ObjectElement> elememts;
    
    
        public RootElement()
        {
            this.elememts = new ArrayList<>();
        }
    
    
        public void add(ObjectElement element)
        {
            this.elememts.add(element);
        }
    
        // ...
    }
    

    Converter:

    public class RootElementConverter implements Converter<RootElement>
    {
        @Override
        public RootElement read(InputNode node) throws Exception
        {
            RootElement root = new RootElement();
    
            /*
             * Iterate over all nodes and add them to root. You can use 
             * "node.getName()" and "node.getAttribute(...)" to test what
             * instance you have to add.
             * 
             * Use "root.add(...)" to add nodes.
             */
    
            return root;
        }
    
    
        @Override
        public void write(OutputNode node, RootElement value) throws Exception
        {
            /*
             * Implement this if you also serialize to xml.
             */
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    

    最后如何调用:

    final String xml = ...
    
    // Important: Don't forget the AnnotationStrategy!
    Serializer ser = new Persister(new AnnotationStrategy());
    
    // Read root-object from xml-string or whatever
    RootElement root = ser.read(RootElement.class, xml);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-18
      • 2019-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-04
      • 1970-01-01
      相关资源
      最近更新 更多