
org.xerial.xml.XMLGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xerial-xml Show documentation
Show all versions of xerial-xml Show documentation
XML Parser/Indexing library.
The newest version!
/*--------------------------------------------------------------------------
* Copyright 2004 Taro L. Saito
*
* Licensed 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.
*--------------------------------------------------------------------------*/
//-----------------------------------
// XerialJ Project
//
// XMLGenerator.java
// Since: 2005/01/16
//
// $Author$
//--------------------------------------
package org.xerial.xml;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.LinkedList;
import org.xerial.core.XerialError;
/**
* XML Generator produces well-formed XML documents
*
* [s1](1) [1][s1] [s2] (2) [s3]
* [s4]
*
* (1) newline before nested element (2) newline after leaf element [1] indent
* before element (indent string SPACE or TAB, indent character size = 2)
*
*
* states:
*
* A (the previous output is starg tag) B (the previous output is text content)
* C (the previous output is end tag)
*
* TODO: on/off of indentation
*
* @author leo
*/
public class XMLGenerator
{
public enum IndentType {
SPACE, TAB
};
private int _currentLevel = 0;
private String _indent = " ";
private PrintWriter _out;
private LinkedList _tagStack = new LinkedList();
public enum FormatStab {
NewlineBeforeNestedElement, NewlineAfterElement, IndentBeforeElement
};
private HashMap _formatEnableFlag = new HashMap();
private enum PreviousOutput {
StartTag, TextContent, EndTag
}
private PreviousOutput _prevOut = PreviousOutput.EndTag;
private boolean isEnable(FormatStab stabType)
{
Boolean b = _formatEnableFlag.get(stabType);
return b == null ? false : b;
}
public XMLGenerator text(String textContent)
{
_out.print(textContent);
_prevOut = PreviousOutput.TextContent;
return this;
}
public XMLGenerator startTag(String tagName)
{
return startTag(tagName, null);
}
void beforeStartTag()
{
switch (_prevOut)
{
case StartTag:
if (isEnable(FormatStab.NewlineBeforeNestedElement))
newline();
case EndTag:
if (isEnable(FormatStab.IndentBeforeElement))
indent(_currentLevel);
break;
}
}
public static String replaceWhiteSpaces(String tagName)
{
return tagName.replaceAll("\\s+", "_");
}
public XMLGenerator startTag(String tagName, XMLAttribute attribute)
{
beforeStartTag();
String tag = replaceWhiteSpaces(tagName);
_out.print("<");
_out.print(tag);
if (attribute != null && attribute.length() > 0)
{
_out.print(" ");
_out.print(attribute.toXMLString());
}
_out.print(">");
_currentLevel++;
_tagStack.add(tag);
_prevOut = PreviousOutput.StartTag;
return this;
}
public XMLGenerator element(String tagName, String textContent)
{
startTag(tagName, null);
text(textContent);
endTag();
return this;
}
public XMLGenerator element(String tagName, XMLAttribute attribute, String textContent)
{
startTag(tagName, attribute);
text(textContent);
endTag();
return this;
}
public XMLGenerator selfCloseTag(String tagName)
{
return selfCloseTag(tagName, null);
}
public XMLGenerator selfCloseTag(String tagName, XMLAttribute attribute)
{
beforeStartTag();
_out.print("<");
_out.print(tagName);
if (attribute != null && attribute.length() > 0)
{
_out.print(" ");
_out.print(attribute.toXMLString());
}
_out.print("/>");
if (isEnable(FormatStab.NewlineAfterElement))
newline();
_prevOut = PreviousOutput.EndTag;
return this;
}
public XMLGenerator endTag()
{
if (_currentLevel < 1)
throw new XerialError(XMLErrorCode.NO_MORE_TAG_TO_CLOSE);
switch (_prevOut)
{
case StartTag:
if (isEnable(FormatStab.NewlineBeforeNestedElement))
newline();
case EndTag:
if (isEnable(FormatStab.IndentBeforeElement))
indent(_currentLevel - 1);
break;
}
String tagName = _tagStack.getLast();
_out.print("");
_out.print(tagName);
_out.print(">");
if (isEnable(FormatStab.NewlineAfterElement))
newline();
_currentLevel--;
_tagStack.removeLast();
_prevOut = PreviousOutput.EndTag;
return this;
}
public XMLGenerator flush()
{
_out.flush();
return this;
}
public void endDocument()
{
while (!_tagStack.isEmpty())
endTag();
_out.flush();
}
private void init()
{
_formatEnableFlag.put(FormatStab.NewlineBeforeNestedElement, true);
_formatEnableFlag.put(FormatStab.NewlineAfterElement, true);
_formatEnableFlag.put(FormatStab.IndentBeforeElement, true);
}
public XMLGenerator()
{
init();
setOutputStream(System.out);
}
public XMLGenerator(OutputStream out)
{
init();
setOutputStream(out);
}
public XMLGenerator(Writer out)
{
init();
setOutputWriter(out);
}
public void setOutputStream(OutputStream out)
{
_out = new PrintWriter(out);
}
public void setOutputWriter(Writer writer)
{
_out = new PrintWriter(writer);
}
/**
*
* @param indentType
* SPACE or TAB
* @param length
* indent size per level
*
*/
public void setIndentCharacter(IndentType indentType, int length)
{
assert length >= 0;
StringBuffer indent = new StringBuffer();
switch (indentType)
{
case SPACE:
for (int i = 0; i < length; i++)
indent.append(" ");
break;
case TAB:
for (int i = 0; i < length; i++)
indent.append("\t");
break;
}
_indent = indent.toString();
}
protected void indent(int level)
{
for (int i = 0; i < level; i++)
_out.print(_indent);
}
protected void newline()
{
_out.println();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy