@@ -145,40 +145,51 @@ private static boolean isSerializationParametersElement(final Item item) {
145
145
* @throws XPathException in case of dynamic error.
146
146
*/
147
147
public static Sequence normalize (final Expression callingExpr , final XQueryContext context , final Sequence input , final String itemSeparator ) throws XPathException {
148
- if (input .isEmpty ())
149
- // "If the sequence that is input to serialization is empty, create a sequence S1 that consists of a zero-length string."
150
- {return StringValue .EMPTY_STRING ;}
151
- final ValueSequence temp = new ValueSequence (input .getItemCount ());
148
+ // "If the sequence that is input to serialization is empty, create a sequence S1 that consists of a zero-length string."
149
+ if (input .isEmpty ()) {
150
+ return StringValue .EMPTY_STRING ;
151
+ }
152
+ // flatten arrays
153
+ final ValueSequence step1 = new ValueSequence ();
152
154
for (final SequenceIterator i = input .iterate (); i .hasNext (); ) {
155
+ final Item next = i .nextItem ();
156
+ if (next .getType () != Type .ARRAY ) {
157
+ step1 .add (next );
158
+ continue ;
159
+ }
160
+ final Sequence sequence = ArrayType .flatten (next );
161
+ if (sequence .isEmpty ()) {
162
+ continue ;
163
+ }
164
+ for (final SequenceIterator si = sequence .iterate (); si .hasNext (); ) {
165
+ step1 .add (si .nextItem ());
166
+ }
167
+ }
168
+
169
+ final ValueSequence step2 = new ValueSequence (step1 .getItemCount ());
170
+ for (final SequenceIterator i = step1 .iterate (); i .hasNext (); ) {
153
171
final Item next = i .nextItem ();
154
172
final int itemType = next .getType ();
155
173
if (Type .subTypeOf (itemType , Type .NODE )) {
156
174
if (itemType == Type .ATTRIBUTE || itemType == Type .NAMESPACE || itemType == Type .FUNCTION_REFERENCE ) {
157
175
throw new XPathException (callingExpr , FnModule .SENR0001 ,
158
176
"It is an error if an item in the sequence to serialize is an attribute node or a namespace node." );
159
177
}
160
- temp .add (next );
161
- } else if (itemType == Type .ARRAY ) {
162
- final Sequence sequence = ArrayType .flatten (next );
163
- if (sequence .isEmpty ()) {
164
- continue ;
165
- }
166
- temp .add (new StringValue (callingExpr , sequence .getStringValue ()));
178
+ step2 .add (next );
167
179
} else {
168
180
// atomic value
169
181
// "For each item in S1, if the item is atomic, obtain the lexical representation of the item by
170
182
// casting it to an xs:string and copy the string representation to the new sequence;"
171
183
final StringValue stringRepresentation = new StringValue (callingExpr , next .getStringValue ());
172
- // skip values that evaluate to an empty string
173
- temp .add (stringRepresentation );
184
+ step2 .add (stringRepresentation );
174
185
}
175
186
}
176
187
177
188
context .pushDocumentContext ();
178
189
try {
179
190
final MemTreeBuilder builder = context .getDocumentBuilder ();
180
191
final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver (callingExpr , builder , true );
181
- for (final SequenceIterator i = temp .iterate (); i .hasNext (); ) {
192
+ for (final SequenceIterator i = step2 .iterate (); i .hasNext (); ) {
182
193
final Item next = i .nextItem ();
183
194
if (Type .subTypeOf (next .getType (), Type .NODE )) {
184
195
next .copyTo (context .getBroker (), receiver );
0 commit comments