The issueFIXatdl schema defines the following structure: <xs:element name="strategyPanel">
<xs:complexType>
<xs:sequence>
<xs:element ref="strategyPanel" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element> With this schema the following XML is valid: <strategyPanel>
<strategyPanel name="panel0" />
<strategyPanel name="panel1" />
<parameter name="parameter0" />
<parameter name="parameter1" />
<strategyPanel name="panel2" />
</strategyPanel> When I generate a XmlBeans parser using the xsd the following interface is generated: public interface StrategyPanel {
public StrategyPanel[] getStrategyPanelArray();
public Parameter[] getParameterArray();
}Using the arrays I can traverse sub-panels and sub-parameters, but how can I traverse through both following the order they appear in the XML (panel0, panel1, parameter0, parameter1, panel2)? The solutionWe can create an Iterator <object> based on the fact that I have access to the org.w3c.Node object of a given StrategyPanel or Parameter (thanks to XmlBeans). I keep track of two cursors and move then correctly. Code below: public class StrategyPanelIterator implements Iterator<Object> {
private StrategyPanel panel;
private int i;
private int paramIndex;
private int panelIndex;
public StrategyPanelIterator(StrategyPanel panel) {
this.panel = panel;
this.i = 0;
this.paramIndex = 0;
this.panelIndex = 0;
}
@Override
public boolean hasNext() {
int length = panel.getDomNode().getChildNodes().getLength();
return i < length;
}
/**
* Returns the current element. The user must check if it's an instanceof
* ParameterT or StrategyPanel.
*/
@Override
public Object next() {
Object ret = null;
int length = panel.getDomNode().getChildNodes().getLength();
while (i < length && ret == null) {
// get i-child
Node node = panel.getDomNode().getChildNodes().item(i);
// se if it matches with current parameter node
if (panel.getParameterArray().length > paramIndex) {
Node parameterNode = panel.getParameterArray(paramIndex)
.getDomNode();
if (parameterNode != null && parameterNode.equals(node)) {
// return it and goes to the next parameter
ret = panel.getParameterArray(paramIndex);
paramIndex++;
}
}
// se if it matches with current panel node
if (panel.getStrategyPanelArray().length > panelIndex) {
Node panelNode = panel.getStrategyPanelArray(panelIndex)
.getDomNode();
if (panelNode != null && panelNode.equals(node)) {
// return it and goes to the next parameter
ret = panel.getStrategyPanelArray(panelIndex);
panelIndex++;
}
}
i++;
}
return ret;
}
@Override
public void remove() {
throw new RuntimeException("operation not supported");
}
}Now, to use this Iterator you must check if the returned Object is an instance of StrategyPanel or Parameter, like this: Iterator<Object> it = new StrategyPanelIterator(panel);
while (it.hasNext()) {
Object obj = it.next();
if (obj instanceof Parameter) {
// handle that
} else if (obj instanceof StrategyPanel) {
// handle that
}
}
|