package com.joe.utilities.core.util;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.apache.commons.lang.StringUtils;
public class StaxUtils
{
/**
* Copies the reader to the writer. The start and end document methods must
* be handled on the writer manually.
*
* @param reader the reader
* @param writer the writer
* @throws XMLStreamException the xML stream exception
*/
public static void copyCurrentElement(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException
{
copyCurrentElement(reader, writer, true);
}
/**
* Copies the reader to the writer for the current element. The start and end document methods must
* be handled on the writer manually.
*
* @param reader the reader
* @param writer the writer
* @param trimText the trim text
* @throws XMLStreamException the xML stream exception
*/
public static void copyCurrentElement(XMLStreamReader reader, XMLStreamWriter writer, boolean trimText) throws XMLStreamException
{
if (reader.getEventType() != XMLStreamConstants.START_ELEMENT)
throw new IllegalArgumentException("Reader must be at start element to perform copy");
int event = reader.getEventType();
String currentElementName = reader.getLocalName();
while (reader.hasNext())
{
switch (event)
{
case XMLStreamConstants.START_ELEMENT:
writeStartElement(reader, writer);
break;
case XMLStreamConstants.END_ELEMENT:
writer.writeEndElement();
if (reader.getLocalName().equals(currentElementName))
return;
break;
case XMLStreamConstants.CHARACTERS:
if (trimText)
writer.writeCharacters(reader.getText().trim());
else
writer.writeCharacters(reader.getText());
break;
case XMLStreamConstants.COMMENT:
if (trimText)
writer.writeComment(reader.getText().trim());
else
writer.writeComment(reader.getText());
break;
case XMLStreamConstants.CDATA:
if (trimText)
writer.writeCData(reader.getText().trim());
else
writer.writeCData(reader.getText());
break;
case XMLStreamConstants.START_DOCUMENT:
case XMLStreamConstants.END_DOCUMENT:
case XMLStreamConstants.ATTRIBUTE:
case XMLStreamConstants.NAMESPACE:
break;
default:
break;
}
event = reader.next();
}
}
/**
* Write start element.
*
* @param reader the reader
* @param writer the writer
* @throws XMLStreamException the xML stream exception
*/
private static void writeStartElement(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException
{
String local = reader.getLocalName();
String uri = reader.getNamespaceURI();
String prefix = reader.getPrefix();
if (prefix == null)
{
prefix = "";
}
// local + " namespace URI" + uri);
boolean writeElementNS = false;
if (uri != null)
{
String boundPrefix = writer.getPrefix(uri);
if (boundPrefix == null || !prefix.equals(boundPrefix))
{
writeElementNS = true;
}
}
// Write out the element name
if (uri != null)
{
if (prefix.length() == 0 && StringUtils.isEmpty(uri))
{
writer.writeStartElement(local);
writer.setDefaultNamespace(uri);
}
else
{
writer.writeStartElement(prefix, local, uri);
writer.setPrefix(prefix, uri);
}
}
else
{
writer.writeStartElement(local);
}
// Write out the namespaces
for (int i = 0; i < reader.getNamespaceCount(); i++)
{
String nsURI = reader.getNamespaceURI(i);
String nsPrefix = reader.getNamespacePrefix(i);
if (nsPrefix == null)
{
nsPrefix = "";
}
if (nsPrefix.length() == 0)
{
writer.writeDefaultNamespace(nsURI);
}
else
{
writer.writeNamespace(nsPrefix, nsURI);
}
if (nsURI.equals(uri) && nsPrefix.equals(prefix))
{
writeElementNS = false;
}
}
// Check if the namespace still needs to be written.
// We need this check because namespace writing works
// different on Woodstox and the RI.
if (writeElementNS)
{
if (prefix == null || prefix.length() == 0)
{
writer.writeDefaultNamespace(uri);
}
else
{
writer.writeNamespace(prefix, uri);
}
}
// Write out attributes
for (int i = 0; i < reader.getAttributeCount(); i++)
{
String ns = reader.getAttributeNamespace(i);
String nsPrefix = reader.getAttributePrefix(i);
if (ns == null || ns.length() == 0)
{
writer.writeAttribute(reader.getAttributeLocalName(i), reader.getAttributeValue(i));
}
else if (nsPrefix == null || nsPrefix.length() == 0)
{
writer.writeAttribute(reader.getAttributeNamespace(i), reader.getAttributeLocalName(i), reader.getAttributeValue(i));
}
else
{
writer.writeAttribute(reader.getAttributePrefix(i), reader.getAttributeNamespace(i), reader.getAttributeLocalName(i), reader.getAttributeValue(i));
}
}
}
}