如何跳过SimpleXML中的特定元素

时间:2016-10-25 10:10:34

标签: java simple-framework visitor

我使用SimpleXML框架反序列化后端答案。我对元素做了一些假设。有些元素不符合这些要求。例如,我希望元素包含子级<ID><face>。如果不允许我的用户查看特定元素,我可能会得到这样的答案:

<list>
  <voucher type="hiddenobject">
    <face>foo</face>
  </voucher>
  <voucher type="object">
    <ID>42</ID>
    <face>bar</face>
  </voucher>
</list>

这给了我以下反序列化类的ValueRequiredException:

@Root
class Voucher {
  @Element(name="ID")
  private String id;

  @Element
  private String face;
}

我想忽略类型为hiddenobject的这些对象。我了解了VisitorStrategy并实现了一个简单的Visitor,如此:

private static final class HiddenObjectVisitor implements Visitor {

    @Override
    public void read(Type type, NodeMap<InputNode> node) throws Exception {
        String nodeType = node.getNode().getAttribute("type").getValue();

        if (nodeType != null && nodeType.equals("hiddenobject")) {
            Log.d(TAG, "skipping node " + node);
            node.getNode().skip();
        }
    }

    @Override
    public void write(Type type, NodeMap<OutputNode> node) throws Exception {
        // stub
    }
}

并将此Visitor添加到VisitorStrategy

VisitorStrategy strategy = new VisitorStrategy(new HiddenObjectVisitor());

期望在反序列化期间这会跳过节点。我确实得到了日志条目,表明将跳过该节点。无论如何,VisitorStrategy似乎一直在解析要跳过的节点,导致ValueRequiredException

如何忽略具有给定属性的节点?是否可以使用VisitorStrategy执行此任务?

2 个答案:

答案 0 :(得分:5)

您可以将Raniz建议的方法与HiddenObjectVisitor结合使用。使用id注释required=false以避免使用ValueRequiredException,然后在反序列化期间使用HiddenObjectVisitor跳过某些Voucher对象。

根据您显示的XML,XML文件中不需要id,这就是required=false指示的内容。但是你暗示在反序列化的对象中需要id,因此你可以在反序列化时丢弃无效的对象。

答案 1 :(得分:4)

您可以做的一件事是将ID标记为optional并包含type属性,以便在反序列化后进行过滤。

@Root
class Voucher {
  @Attribute
  private String type;

  @Element(name="ID", required=false)
  private String id;

  @Element
  private String face;
}

然后,您可以在反序列化后过滤凭证:

// Deserialise the XML
List<Voucher> vouchers = ...;

// Filter the list of vouchers
List<Voucher> nonHiddenVouchers = new ArrayList<>();
for (Voucher voucher : vouchers) {
    if (!"hiddenobject".equals(voucher.getType())) {
        nonHiddenVouchers.add(voucher);
    }
}