如何跳过 SimpleXML 中的特定元素

How to skip specific element in SimpleXML

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

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

这为我提供了以下反序列化的 ValueRequiredException class:

@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 来完成这项任务?

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

@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);
    }
}

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

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