import java.io.IOException;
import java.io.Writer;
import java.util.Stack;
import com.generationjava.io.WritingException;
/**
* Makes writing XML much much easier.
*
* @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
* @version 0.1
*/
public class XmlWriter {
private Writer writer; // underlying writer
private Stack stack; // of xml entity names
private StringBuffer attrs; // current attribute string
private boolean empty; // is the current node empty
private boolean closed; // is the current node closed...
/**
* Create an XmlWriter on top of an existing java.io.Writer.
*/
public XmlWriter(Writer writer) {
this.writer = writer;
this.closed = true;
this.stack = new Stack();
}
/**
* Begin to output an entity.
*
* @param String name of entity.
*/
public XmlWriter writeEntity(String name) throws WritingException {
try {
closeOpeningTag();
this.closed = false;
this.writer.write("<");
this.writer.write(name);
stack.add(name);
this.empty = true;
return this;
} catch (IOException ioe) {
throw new XmlWritingException(ioe);
}
}
// close off the opening tag
private void closeOpeningTag() throws IOException {
if (!this.closed) {
writeAttributes();
this.closed = true;
this.writer.write(">");
}
}
// write out all current attributes
private void writeAttributes() throws IOException {
if (this.attrs != null) {
this.writer.write(this.attrs.toString());
this.attrs.setLength(0);
this.empty = false;
}
}
/**
* Write an attribute out for the current entity.
* Any xml characters in the value are escaped.
* Currently it does not actually throw the exception, but
* the api is set that way for future changes.
*
* @param String name of attribute.
* @param String value of attribute.
*/
public XmlWriter writeAttribute(String attr, String value) throws WritingException {
// maintain api
if (false) throw new XmlWritingException();
if (this.attrs == null) {
this.attrs = new StringBuffer();
}
this.attrs.append(" ");
this.attrs.append(attr);
this.attrs.append("=\"");
this.attrs.append(escapeXml(value));
this.attrs.append("\"");
return this;
}
/**
* End the current entity. This will throw an exception
* if it is called when there is not a currently open
* entity.
*/
public XmlWriter endEntity() throws WritingException {
try {
if(this.stack.empty()) {
throw new XmlWritingException("Called endEntity too many times. ");
}
String name = (String)this.stack.pop();
if (name != null) {
if (this.empty) {
writeAttributes();
this.writer.write("/>");
} else {
this.writer.write("</");
this.writer.write(name);
this.writer.write(">");
}
this.empty = false;
}
return this;
} catch (IOException ioe) {
throw new XmlWritingException(ioe);
}
}
/**
* Close this writer. It does not close the underlying
* writer, but does throw an exception if there are
* as yet unclosed tags.
*/
public void close() throws WritingException {
if(!this.stack.empty()) {
throw new XmlWritingException("Tags are not all closed. "+
"Possibly, "+this.stack.pop()+" is unclosed. ");
}
}
/**
* Output body text. Any xml characters are escaped.
*/
public XmlWriter writeText(String text) throws WritingException {
try {
closeOpeningTag();
this.empty = false;
this.writer.write(escapeXml(text));
return this;
} catch (IOException ioe) {
throw new XmlWritingException(ioe);
}
}
// Static functions lifted from generationjava helper classes
// to make the jar smaller.
// from XmlW
static public String escapeXml(String str) {
str = replaceString(str,"&","&");
str = replaceString(str,"<","<");
str = replaceString(str,">",">");
str = replaceString(str,"\"",""");
str = replaceString(str,"'","'");
return str;
}
// from StringW
static public String replaceString(String text, String repl, String with) {
return replaceString(text, repl, with, -1);
}
/**
* Replace a string with another string inside a larger string, for
* the first n values of the search string.
*
* @param text String to do search and replace in
* @param repl String to search for
* @param with String to replace with
* @param n int values to replace
*
* @return String with n values replacEd
*/
static public String replaceString(String text, String repl, String with, int max) {
if(text == null) {
return null;
}
StringBuffer buffer = new StringBuffer(text.length());
int start = 0;
int end = 0;
while( (end = text.indexOf(repl, start)) != -1 ) {
buffer.append(text.substring(start, end)).append(with);
start = end + repl.length();
if(--max == 0) {
break;
}
}
buffer.append(text.substring(start));
return buffer.toString();
}
// Two example methods. They should output the same XML:
// <person name="fred" age="12"><phone>425343</phone><bob/></person>
static public void main(String[] args) throws WritingException {
test1();
test2();
}
static public void test1() throws WritingException {
Writer writer = new java.io.StringWriter();
XmlWriter xmlwriter = new XmlWriter(writer);
xmlwriter.writeEntity("person").writeAttribute("name", "fred").writeAttribute("age", "12").writeEntity("phone").writeText("4254343").endEntity().writeEntity("bob").endEntity().endEntity();
xmlwriter.close();
System.err.println(writer.toString());
}
static public void test2() throws WritingException {
Writer writer = new java.io.StringWriter();
XmlWriter xmlwriter = new XmlWriter(writer);
xmlwriter.writeEntity("person");
xmlwriter.writeAttribute("name", "fred");
xmlwriter.writeAttribute("age", "12");
xmlwriter.writeEntity("phone");
xmlwriter.writeText("4254343");
xmlwriter.endEntity();
xmlwriter.writeEntity("bob");
xmlwriter.endEntity();
xmlwriter.endEntity();
xmlwriter.close();
System.err.println(writer.toString());
}
}
C#에는 있는데 왜 자바에는 없는거냐..ㅡ.ㅡ
import java.io.Writer;
import java.util.Stack;
import com.generationjava.io.WritingException;
/**
* Makes writing XML much much easier.
*
* @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
* @version 0.1
*/
public class XmlWriter {
private Writer writer; // underlying writer
private Stack stack; // of xml entity names
private StringBuffer attrs; // current attribute string
private boolean empty; // is the current node empty
private boolean closed; // is the current node closed...
/**
* Create an XmlWriter on top of an existing java.io.Writer.
*/
public XmlWriter(Writer writer) {
this.writer = writer;
this.closed = true;
this.stack = new Stack();
}
/**
* Begin to output an entity.
*
* @param String name of entity.
*/
public XmlWriter writeEntity(String name) throws WritingException {
try {
closeOpeningTag();
this.closed = false;
this.writer.write("<");
this.writer.write(name);
stack.add(name);
this.empty = true;
return this;
} catch (IOException ioe) {
throw new XmlWritingException(ioe);
}
}
// close off the opening tag
private void closeOpeningTag() throws IOException {
if (!this.closed) {
writeAttributes();
this.closed = true;
this.writer.write(">");
}
}
// write out all current attributes
private void writeAttributes() throws IOException {
if (this.attrs != null) {
this.writer.write(this.attrs.toString());
this.attrs.setLength(0);
this.empty = false;
}
}
/**
* Write an attribute out for the current entity.
* Any xml characters in the value are escaped.
* Currently it does not actually throw the exception, but
* the api is set that way for future changes.
*
* @param String name of attribute.
* @param String value of attribute.
*/
public XmlWriter writeAttribute(String attr, String value) throws WritingException {
// maintain api
if (false) throw new XmlWritingException();
if (this.attrs == null) {
this.attrs = new StringBuffer();
}
this.attrs.append(" ");
this.attrs.append(attr);
this.attrs.append("=\"");
this.attrs.append(escapeXml(value));
this.attrs.append("\"");
return this;
}
/**
* End the current entity. This will throw an exception
* if it is called when there is not a currently open
* entity.
*/
public XmlWriter endEntity() throws WritingException {
try {
if(this.stack.empty()) {
throw new XmlWritingException("Called endEntity too many times. ");
}
String name = (String)this.stack.pop();
if (name != null) {
if (this.empty) {
writeAttributes();
this.writer.write("/>");
} else {
this.writer.write("</");
this.writer.write(name);
this.writer.write(">");
}
this.empty = false;
}
return this;
} catch (IOException ioe) {
throw new XmlWritingException(ioe);
}
}
/**
* Close this writer. It does not close the underlying
* writer, but does throw an exception if there are
* as yet unclosed tags.
*/
public void close() throws WritingException {
if(!this.stack.empty()) {
throw new XmlWritingException("Tags are not all closed. "+
"Possibly, "+this.stack.pop()+" is unclosed. ");
}
}
/**
* Output body text. Any xml characters are escaped.
*/
public XmlWriter writeText(String text) throws WritingException {
try {
closeOpeningTag();
this.empty = false;
this.writer.write(escapeXml(text));
return this;
} catch (IOException ioe) {
throw new XmlWritingException(ioe);
}
}
// Static functions lifted from generationjava helper classes
// to make the jar smaller.
// from XmlW
static public String escapeXml(String str) {
str = replaceString(str,"&","&");
str = replaceString(str,"<","<");
str = replaceString(str,">",">");
str = replaceString(str,"\"",""");
str = replaceString(str,"'","'");
return str;
}
// from StringW
static public String replaceString(String text, String repl, String with) {
return replaceString(text, repl, with, -1);
}
/**
* Replace a string with another string inside a larger string, for
* the first n values of the search string.
*
* @param text String to do search and replace in
* @param repl String to search for
* @param with String to replace with
* @param n int values to replace
*
* @return String with n values replacEd
*/
static public String replaceString(String text, String repl, String with, int max) {
if(text == null) {
return null;
}
StringBuffer buffer = new StringBuffer(text.length());
int start = 0;
int end = 0;
while( (end = text.indexOf(repl, start)) != -1 ) {
buffer.append(text.substring(start, end)).append(with);
start = end + repl.length();
if(--max == 0) {
break;
}
}
buffer.append(text.substring(start));
return buffer.toString();
}
// Two example methods. They should output the same XML:
// <person name="fred" age="12"><phone>425343</phone><bob/></person>
static public void main(String[] args) throws WritingException {
test1();
test2();
}
static public void test1() throws WritingException {
Writer writer = new java.io.StringWriter();
XmlWriter xmlwriter = new XmlWriter(writer);
xmlwriter.writeEntity("person").writeAttribute("name", "fred").writeAttribute("age", "12").writeEntity("phone").writeText("4254343").endEntity().writeEntity("bob").endEntity().endEntity();
xmlwriter.close();
System.err.println(writer.toString());
}
static public void test2() throws WritingException {
Writer writer = new java.io.StringWriter();
XmlWriter xmlwriter = new XmlWriter(writer);
xmlwriter.writeEntity("person");
xmlwriter.writeAttribute("name", "fred");
xmlwriter.writeAttribute("age", "12");
xmlwriter.writeEntity("phone");
xmlwriter.writeText("4254343");
xmlwriter.endEntity();
xmlwriter.writeEntity("bob");
xmlwriter.endEntity();
xmlwriter.endEntity();
xmlwriter.close();
System.err.println(writer.toString());
}
}
C#에는 있는데 왜 자바에는 없는거냐..ㅡ.ㅡ
'프로그래밍' 카테고리의 다른 글
[ireport] ireport bean클래스 파일 사용해서 필드명 바인드하기 (0) | 2011.01.21 |
---|---|
[펌] 자바 파일 입출력시 글자깨짐 문제 (0) | 2010.12.27 |
C# 과 JAVA 의 이스케이프 코드 차이점 (0) | 2010.12.09 |
[NetBeans] setDisable() 관련 문제 (0) | 2010.11.25 |
[기타] 자바스크립트 객체 제어 (0) | 2010.11.17 |