All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.rdf4j.common.xml.XMLWriter Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2015 Eclipse RDF4J contributors, Aduna, and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Distribution License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *******************************************************************************/

package org.eclipse.rdf4j.common.xml;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * A utility class offering convenience methods for writing XML. This class takes care of character escaping,
 * identation, etc. This class does not verify that the written data is legal XML. It is the callers responsibility to
 * make sure that elements are properly nested, etc.
 * 

Example:

*

* To write the following XML: * *

 * <?xml version='1.0' encoding='UTF-8'?>
 * <xml-doc>
 * <foo a="1" b="2&amp;3"/>
 * <bar>Hello World!</bar>
 * </xml-doc>
 * 
*

* One can use the following code: * *

 * XMLWriter xmlWriter = new XMLWriter(myWriter);
 * xmlWriter.setPrettyPrint(true);
 *
 * xmlWriter.startDocument();
 * xmlWriter.startTag("xml-doc");
 *
 * xmlWriter.setAttribute("a", 1);
 * xmlWriter.setAttribute("b", "2&3");
 * xmlWriter.simpleTag("foo");
 *
 * xmlWriter.textTag("bar", "Hello World!");
 *
 * xmlWriter.endTag("xml-doc");
 * xmlWriter.endDocument();
 * 
*/ public class XMLWriter { /*-----------* * Constants * *-----------*/ /** * The (platform-dependent) line separator. */ private static final String LINE_SEPARATOR = System.getProperty("line.separator"); /*-----------* * Variables * *-----------*/ /** * The writer to write the XML to. */ private final Writer _writer; /** * The required character encoding of the written data. */ private String _charEncoding; /** * Flag indicating whether the output should be printed pretty, i.e. adding newlines and indentation. */ private boolean _prettyPrint = false; /** * The current indentation level, i.e. the number of tabs to indent a start or end tag. */ protected int _indentLevel = 0; /** * The string to use for indentation, e.g. a tab or a number of spaces. */ private String _indentString = "\t"; /** * A mapping from attribute names to values for the next start tag. */ private final Map _attributes = new LinkedHashMap<>(); /*--------------* * Constructors * *--------------*/ /** * Creates a new XMLWriter that will write its data to the supplied Writer. Character encoding issues are left to * the supplier of the Writer. * * @param writer The Writer to write the XML to. */ public XMLWriter(Writer writer) { _writer = writer; } /** * Creates a new XMLWriter that will write its data to the supplied OutputStream in the default UTF-8 character * encoding. * * @param outputStream The OutputStream to write the XML to. */ public XMLWriter(OutputStream outputStream) { _charEncoding = StandardCharsets.UTF_8.name(); _writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); } /** * Creates a new XMLWriter that will write its data to the supplied OutputStream in specified character encoding. * * @param outputStream The OutputStream to write the XML to. */ public XMLWriter(OutputStream outputStream, String charEncoding) throws UnsupportedEncodingException { _charEncoding = charEncoding; _writer = new OutputStreamWriter(outputStream, _charEncoding); } /*---------* * Methods * *---------*/ /** * Enables or disables pretty-printing. If pretty-printing is enabled, the XMLWriter will add newlines and * indentation to the written data. Pretty-printing is disabled by default. * * @param prettyPrint Flag indicating whether pretty-printing should be enabled. */ public void setPrettyPrint(boolean prettyPrint) { _prettyPrint = prettyPrint; } /** * Checks whether pretty-printing is enabled. * * @return true if pretty-printing is enabled, false otherwise. */ public boolean prettyPrintEnabled() { return _prettyPrint; } /** * @return the writer */ public Writer getWriter() { return _writer; } /** * Sets the string that should be used for indentation when pretty-printing is enabled. The default indentation * string is a tab character. * * @param indentString The indentation string, e.g. a tab or a number of spaces. */ public void setIndentString(String indentString) { _indentString = indentString; } /** * Gets the string used for indentation. * * @return the indentation string. */ public String getIndentString() { return _indentString; } /** * Writes the XML header for the XML file. * * @throws IOException If an I/O error occurs. */ public void startDocument() throws IOException { _write(""); } /** * Finishes writing and flushes the OutputStream or Writer that this XMLWriter is writing to. */ public void endDocument() throws IOException { getWriter().flush(); } /** * Sets an attribute for the next start tag. * * @param name The name of the attribute. * @param value The value of the attribute. */ public void setAttribute(String name, String value) { _attributes.put(name, value); } /** * Sets an attribute for the next start element. * * @param name The name of the attribute. * @param value The value of the attribute. The integer value will be transformed to a string using the method * String.valueOf(int). * @see java.lang.String#valueOf(int) */ public void setAttribute(String name, int value) { setAttribute(name, String.valueOf(value)); } /** * Sets an attribute for the next start element. * * @param name The name of the attribute. * @param value The value of the attribute. The boolean value will be transformed to a string using the method * String.valueOf(boolean). * @see java.lang.String#valueOf(boolean) */ public void setAttribute(String name, boolean value) { setAttribute(name, String.valueOf(value)); } /** * Writes a start tag containing the previously set attributes. * * @param elName The element name. * @see #setAttribute(java.lang.String, java.lang.String) */ public void startTag(String elName) throws IOException { _writeIndent(); _write("<" + elName); _writeAtts(); _writeLn(">"); _indentLevel++; } /** * Writes an end tag. * * @param elName The element name. */ public void endTag(String elName) throws IOException { _indentLevel--; _writeIndent(); _writeLn(""); } /** * Writes an 'empty' element, e.g. <foo/>. The tag will contain any previously set attributes. * * @param elName The element name. * @see #setAttribute(java.lang.String, java.lang.String) */ public void emptyElement(String elName) throws IOException { _writeIndent(); _write("<" + elName); _writeAtts(); _writeLn("/>"); } /** * Writes a link to an XSL stylesheet, using <?xml-stylesheet type='text/xsl' href='url'?>. * * @param url The URL of the stylesheet. */ public void writeStylesheet(String url) throws IOException { _write(""); } /** * Writes a start and end tag with the supplied text between them. The start tag will contain any previously set * attributes. * * @param elName The element name. * @param text The text. * @see #setAttribute(java.lang.String, java.lang.String) */ public void textElement(String elName, String text) throws IOException { _writeIndent(); _write("<" + elName); _writeAtts(); _write(">"); text(text); _writeLn(""); } /** * Writes a start and end tag with the supplied text between them, without the usual escape rules. The start tag * will contain any previously set attributes. * * @param elName The element name. * @param text The text. * @see #setAttribute(java.lang.String, java.lang.String) */ public void unescapedTextElement(String elName, String text) throws IOException { _writeIndent(); _write("<" + elName); _writeAtts(); _write(">"); _write(text); _writeLn(""); } /** * Writes a start and end tag with the supplied value between them. The start tag will contain any previously set * attributes. * * @param elName The element name. * @param value The value. The integer value will be transformed to a string using the method * String.valueOf(int). * @see java.lang.String#valueOf(int) */ public void textElement(String elName, int value) throws IOException { textElement(elName, String.valueOf(value)); } /** * Writes a start and end tag with the supplied boolean value between them. The start tag will contain any * previously set attributes. * * @param elName The element name. * @param value The boolean value. The integer value will be transformed to a string using the method * String.valueOf(boolean). * @see java.lang.String#valueOf(boolean) */ public void textElement(String elName, boolean value) throws IOException { textElement(elName, String.valueOf(value)); } /** * Writes a piece of text. * * @param text The text. */ public void text(String text) throws IOException { _write(XMLUtil.escapeCharacterData(text)); } /** * Writes a comment. * * @param comment The comment. */ public void comment(String comment) throws IOException { _writeIndent(); _writeLn(""); } /** * Writes an empty line. A call to this method will be ignored when pretty-printing is disabled. * * @see #setPrettyPrint */ public void emptyLine() throws IOException { _writeLn(""); } /** * Writes any set attributes and clears them afterwards. */ private void _writeAtts() throws IOException { for (Entry entry : _attributes.entrySet()) { String name = entry.getKey(); String value = entry.getValue(); _write(" " + name + "='"); if (value != null) { _write(XMLUtil.escapeSingleQuotedAttValue(value)); } _write("'"); } _attributes.clear(); } /** * Writes a string. */ protected void _write(String s) throws IOException { getWriter().write(s); } /** * Writes a string followed by a line-separator. The line-separator is not written when pretty-printing is disabled. */ protected void _writeLn(String s) throws IOException { _write(s); if (_prettyPrint) { _write(LINE_SEPARATOR); } } /** * Writes as much indentation strings as appropriate for the current indentation level. A call to this method is * ignored when pretty-printing is disabled. */ protected void _writeIndent() throws IOException { if (_prettyPrint) { for (int i = 0; i < _indentLevel; i++) { _write(_indentString); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy