如何跳过 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
,所以你可以在反序列化时丢弃无效的对象。
我正在使用 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
,所以你可以在反序列化时丢弃无效的对象。