Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to skip specific element in SimpleXML

I am using SimpleXML framework for deserializing backend answers. I made some assumptions about elements. Some elements do not meet these requirements. For example, I expect an element to have childs <ID> and <face>. If my user is not allowed to see a specific element, I might get an answer like this:

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

Which gives me a ValueRequiredException for the following deserialization class:

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

  @Element
  private String face;
}

I would like to ignore these objects with type hiddenobject. I learned about the VisitorStrategy and implemented a simple Visitor like so:

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
    }
}

and added this Visitor to a VisitorStrategy

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

expecting that this would skip nodes during deserialization. I do get log entries stating that the node would be skipped. Anyway, the VisitorStrategy seems to keep parsing the node to be skipped, resulting in a ValueRequiredException.

How can I ignore nodes having a given attribute? Is it possible to use VisitorStrategy for this task?

like image 349
Jeremy Avatar asked Oct 25 '16 10:10

Jeremy


People also ask

What is PHP SimpleXML and how to use it?

Once it is applied, SimpleXML organizes the content of an XML document so you could retrieve information on different elements and their attributes. You can even add new child elements to an element and count them. As the name suggests, PHP SimpleXML is best-suited for small and XML files with a simple structure.

How do I access the underlying element in simplexmlelement?

When you echo or print a node's value, PHP converts the value (a resource) into a string object for you. It's a time saver for sure, but can fool you into thinking that your SimpleXMLElement is an object. To access the underlying element as a string, it's necessary to make the cast $x = (string)$my_xml_element.

Can I add an XML processing instruction to a simplexmlelement?

It's occasionally useful to add an XML processing instruction to a SimpleXMLElement (treating it as if it were a full document). Adds a new function for SimpleXMLElement class, in order to output HTML code.

What is system XML SKIP method?

Xml Reader. Skip Method System. Xml Skips the children of the current node. An XmlReader method was called before a previous asynchronous operation finished. In this case, InvalidOperationException is thrown with the message "An asynchronous operation is already in progress."


1 Answers

You could probably combine the approach suggested by Raniz with your HiddenObjectVisitor. Annotate id with required=false to avoid the ValueRequiredException, and then use your HiddenObjectVisitor to skip some of the Voucher objects during deserialization.

Based on the XML that you have shown, id is not required in the XML file, and that is what required=false indicates. But you imply that id is required in your deserialized objects, so you can discard the invalid objects at the time of deserialization.

like image 55
Enwired Avatar answered Oct 15 '22 00:10

Enwired