I have a nested XML structure based in an XSD. I use JAXB for unmarshalling (read only).
Regularly, I need to find one or more elements somewhere in the large structure. To avoid traversing the structure each time I need to search, I would like to add an optimized search function with an internal cache.
What it the optimal way to define that? What are pro/cons for different ways?
I initially thought of using a facade or an adapter, where the adaper class accesses the generated class and adds methods as needed; however I would like to ask for recommendations.
As a (slightly) simplified example, an XML based on this XSD needs to be searched for Elements of type "step" having a certain "boq" element:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="test">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="group"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="group">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="step"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="step">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="number"/>
<xs:element ref="name"/>
<xs:element ref="type"/>
<xs:element ref="target"/>
<xs:sequence minOccurs="0">
<xs:element ref="boq"/>
<xs:element ref="remote"/>
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="number" type="xs:integer"/>
<xs:element name="name" type="xs:NCName"/>
<xs:element name="type" type="xs:NCName"/>
<xs:element name="target" type="xs:NCName"/>
<xs:element name="boq" type="xs:string"/>
<xs:element name="remote" type="xs:string"/>
</xs:schema>
That Schema has been compiled using JAXB, so I get several classes. Using the unmarshalling Features, I have the data structure in memory that accesses my XML.
Consider now, I need an optimized search function, that accesses all steps where a boq element is defined, and return the value of boq and remote (if also defined).
HashMap<String,Step> resultMap = new HashMap<>();
test.getGroup().forEach(group ->
group.getStep().forEach(step -> {
if ("searchpattern".equals(step.getBoq()))
resultMap.put("searchpattern", step);
}));
What is the best way to do encapsulate such a search? I could write a second class as an adaptor that includes this method, or are there better options? Inheritance? using the Options of JAXB itself? using a third-party plugin such as the jaxb-delegate plugin for maven?