Github user ottobackwards commented on a diff in the pull request: https://github.com/apache/nifi/pull/2675#discussion_r187591727 --- Diff: nifi-nar-bundles/nifi-standard-services/nifi-record-serialization-services-bundle/nifi-record-serialization-services/src/main/java/org/apache/nifi/xml/WriteXMLResult.java --- @@ -0,0 +1,602 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.nifi.xml; + +import javanet.staxutils.IndentingXMLStreamWriter; +import org.apache.nifi.NullSuppression; +import org.apache.nifi.logging.ComponentLog; +import org.apache.nifi.schema.access.SchemaAccessWriter; +import org.apache.nifi.serialization.AbstractRecordSetWriter; +import org.apache.nifi.serialization.RecordSetWriter; +import org.apache.nifi.serialization.WriteResult; +import org.apache.nifi.serialization.record.DataType; +import org.apache.nifi.serialization.record.RawRecordWriter; +import org.apache.nifi.serialization.record.Record; +import org.apache.nifi.serialization.record.RecordField; +import org.apache.nifi.serialization.record.RecordFieldType; +import org.apache.nifi.serialization.record.RecordSchema; +import org.apache.nifi.serialization.record.type.ArrayDataType; +import org.apache.nifi.serialization.record.type.ChoiceDataType; +import org.apache.nifi.serialization.record.type.MapDataType; +import org.apache.nifi.serialization.record.type.RecordDataType; +import org.apache.nifi.serialization.record.util.DataTypeUtils; + +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; + + +public class WriteXMLResult extends AbstractRecordSetWriter implements RecordSetWriter, RawRecordWriter { + + final ComponentLog logger; + final RecordSchema recordSchema; + final SchemaAccessWriter schemaAccess; + final XMLStreamWriter writer; + final NullSuppression nullSuppression; + final ArrayWrapping arrayWrapping; + final String arrayTagName; + final String recordTagName; + final String rootTagName; + + private final Supplier<DateFormat> LAZY_DATE_FORMAT; + private final Supplier<DateFormat> LAZY_TIME_FORMAT; + private final Supplier<DateFormat> LAZY_TIMESTAMP_FORMAT; + + public WriteXMLResult(final ComponentLog logger, final RecordSchema recordSchema, final SchemaAccessWriter schemaAccess, final OutputStream out, final boolean prettyPrint, + final NullSuppression nullSuppression, final ArrayWrapping arrayWrapping, final String arrayTagName, final String rootTagName, final String recordTagName, + final String dateFormat, final String timeFormat, final String timestampFormat) throws IOException { + + super(out); + + this.logger = logger; + this.recordSchema = recordSchema; + this.schemaAccess = schemaAccess; + this.nullSuppression = nullSuppression; + + this.arrayWrapping = arrayWrapping; + this.arrayTagName = arrayTagName; + + this.rootTagName = rootTagName; + this.recordTagName = recordTagName; + + final DateFormat df = dateFormat == null ? null : DataTypeUtils.getDateFormat(dateFormat); + final DateFormat tf = timeFormat == null ? null : DataTypeUtils.getDateFormat(timeFormat); + final DateFormat tsf = timestampFormat == null ? null : DataTypeUtils.getDateFormat(timestampFormat); + + LAZY_DATE_FORMAT = () -> df; + LAZY_TIME_FORMAT = () -> tf; + LAZY_TIMESTAMP_FORMAT = () -> tsf; + + try { + XMLOutputFactory factory = XMLOutputFactory.newInstance(); + + if (prettyPrint) { + writer = new IndentingXMLStreamWriter(factory.createXMLStreamWriter(out)); + } else { + writer = factory.createXMLStreamWriter(out); + } + + } catch (XMLStreamException e) { + throw new IOException(e.getMessage()); + } + } + + @Override + protected void onBeginRecordSet() throws IOException { + + final OutputStream out = getOutputStream(); + schemaAccess.writeHeader(recordSchema, out); + + try { + writer.writeStartDocument(); + + writer.writeStartElement(rootTagName); + + } catch (XMLStreamException e) { + throw new IOException(e.getMessage()); + } + } + + @Override + protected Map<String, String> onFinishRecordSet() throws IOException { + + try { + writer.writeEndElement(); + writer.writeEndDocument(); + } catch (XMLStreamException e) { + throw new IOException(e.getMessage()); + } + return schemaAccess.getAttributes(recordSchema); + } + + @Override + public void close() throws IOException { + + try { + writer.close(); + + } catch (XMLStreamException e) { + throw new IOException(e.getMessage()); + } + + super.close(); + } + + @Override + public void flush() throws IOException { + + try { + writer.flush(); + + } catch (XMLStreamException e) { + throw new IOException(e.getMessage()); + } + } + + @Override + protected Map<String, String> writeRecord(Record record) throws IOException { + + if (!isActiveRecordSet()) { + schemaAccess.writeHeader(recordSchema, getOutputStream()); + } + + List<String> tagsToOpen = new ArrayList<>(); --- End diff -- https://docs.oracle.com/javase/7/docs/api/java/util/Deque.html
---