InternalExpressionContext expressionContext =
(InternalExpressionContext)
context.getExpressionContext();
// The iterator that is returned.
EndElementAction action;
// Evaluate the in expression to a sequence.
String inExpression = attributes.getValue("in");
final Sequence sequence = evaluateExpression(expressionContext, inExpression);
int length = sequence.getLength();
if (length == 0) {
// The sequence is empty so there is nothing to do so just skip
// the body and do not create an iterator.
context.getFlowControlManager().exitCurrentElement();
action = EndElementAction.DO_NOTHING;
} else {
// Resolve the variable name into an ExpandedName, if the variable
// name does not have a prefix then it belongs in no namespace,
// rather than the default namespace.
String variableName = attributes.getValue("variable");
QName variableQName = new ImmutableQName(variableName);
final ExpandedName variableExpandedName =
context.getNamespacePrefixTracker()
.resolveQName(variableQName, null);
// If the sequence only has a single value in then it is not
// necessary to store the body away to be evaluated multiple times.
if (length == 1) {
// Create a new block scope to contain the variable.
expressionContext.pushBlockScope();
// Create a variable in the current stack frame.
try {
expressionContext.getCurrentScope()
.declareVariable(variableExpandedName,
sequence.getItem(1));
} catch (SequenceIndexOutOfBoundsException e) {
throw new ExtendedSAXException(e);
}
// Remember to pop the block scope off after the content has
// been processed.
action = new PopBlockScopeAction();
} else {
// Make the dynamic process pass the element contents straight
// through without evaluating them so that they can be recprded
// and evaluated for each value of the variable. The dynamic
// process will automatically come out of pass through mode
// once it sees the matching end element event.
dynamicProcess.passThroughElementContents();
XMLPipelineFactory factory = context.getPipelineFactory();
final PipelineRecorder recorder =
factory.createPipelineRecorder();
recorder.startRecording(dynamicProcess.getPipeline());
final XMLProcess process = recorder.getRecordingProcess();
dynamicProcess.addProcess(process);
// Create an action to wrap the iterator and remove the
// recording process once the body has been evaluated.
action = new EndElementAction() {
public void doAction(DynamicProcess dynamicProcess)
throws SAXException {
// Remove the process from the head.
dynamicProcess.removeProcess(process);