📄 echoashtml.java
字号:
package MyNa.xml;
import MyNa.utils.*;
/* EchoAsHtml.java does a simple XML to HTML conversion,
driven by an Env which contains parameters such as
echo_inputFileName, echo_indentSpace and so on, but also
contains tag mappings. By default, each XML tag <xyz> becomes
a class of a span: <span class='xyz'>, and the closing </xyz>
becomes </span>. However, if the Env defins xyz as 'h3', then
we get <h3 class='xyz'> and the closing becomes </h3>. This
is of course not applied to CDATA blocks, which are simply
echoed without processing.
The head is produced as
"<head><title>" + inputFileName + "</title></head>"
unless the env contains a definition for echo_head, which
is produced.
*/
import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.ParserFactory;
import com.sun.xml.parser.Resolver;
import com.sun.xml.parser.LexicalEventListener;
import java.lang.Class;
import java.lang.reflect.Constructor;
public class EchoAsHtml extends HandlerBase
implements LexicalEventListener{
Env defs;
String nonValidatingParserName="com.sun.xml.parser.Parser";
String validatingParserName="com.sun.xml.parser.ValidatingParser";
PrintWriter out;
String inputFileName;
String indentSpace;
String parserName;
String lineEnd;
int indentLevel;
boolean validation;
String cDATAWrap;
String parsedEntityWrap;
boolean inCDATA;
boolean inParsedEntity;
Logger lg;
public EchoAsHtml(){
defs=null;
out=null;
indentSpace=" ";
inputFileName=null;
indentLevel=0;
lineEnd=System.getProperty("line.separator");
parserName=nonValidatingParserName;
validation=false;
cDATAWrap = "xmp";
parsedEntityWrap="xmp";
boolean inCDATA=false;
boolean inParsedEntity=false;
lg=new Logger();
lg.logIt("cDATAWrap="+cDATAWrap+"; parsedEntityWrap="+
parsedEntityWrap);
}
public EchoAsHtml(PrintWriter o){
this();
setOut(o);
}
public void doIt()throws IOException{
doIt(inputFileName);
}
public void setOut(PrintWriter o){
out=o;
defs.put("echo_out",o);
}
public void setInputFileName(String S){
inputFileName=S;
defs.put("echo_inputFileName",S);
}
public void setIndentSpace(String S){
indentSpace=S;
defs.put("echo_indentSpace",S);
}
public void setIndentLevel(int N){
indentLevel=N;
defs.put("echo_indentLevel",""+N);
}
public void setParserName(String S){
parserName=S;
defs.put("echo_parserName",S);
}
public void setCDATAWrap(String S){
cDATAWrap=S;
defs.put("echo_CDATAWrap",S);
}
public void setParsedEntityWrap(String S){
parsedEntityWrap=S;
defs.put("echo_ParsedEntityWrap",S);
}
public void setValidation(boolean B){
validation=B;
defs.put("echo_validation",""+B);
if(B)setParserName(validatingParserName);
else setParserName(nonValidatingParserName);
}
/*
setEnv allows control by servlet, applet or main; we can
Env e=new Env();
E.put("echo_out",new OutputStreamWriter(System.out, "UTF8"));
E.put("echo_inputFileName","file:///C:/MyNa/xml/test.xml");
E.put("echo_indentSpace"," ");
E.put("echo_indentLevel","4");
E.put("echo_nonValidatingParserName",....)
E.put("echo_validatingParserName",...);
E.put("echo_validation","true");
E.put("echo_head",
"<head><title>Narcissus&Echo</title></head>");
EchoAsHtml eAH=new EchoAsHtml();
eAH.setEnv(e);
and each of the items in question will be set properly.
Note that indentSpace and indentLevel are only relevant
to a view which actually exposes the source.
*/
public void setEnv(Env E){
defs=E; if(null==defs)return;
Object o=defs.get("echo_out");
if(o instanceof PrintWriter){out=(PrintWriter)o;}
String S=defs.getStr("echo_inputFileName");
if(null!=S)setInputFileName(S);
S=defs.getStr("echo_indentSpace");
if(null!=S)setIndentSpace(S);
S=defs.getStr("echo_indentLevel");
if(null!=S)indentLevel=(new Integer(S)).intValue(); // "5"|"12"|..
S=defs.getStr("echo_nonValidatingParserName");
if(null!=S)nonValidatingParserName=S;
S=defs.getStr("echo_validatingParserName");
if(null!=S)validatingParserName=S;
S=defs.getStr("echo_parserName");
if(null!=S)setParserName(S);
S=defs.getStr("echo_CDATAWrap");
if(null!=S)setCDATAWrap(S);
S=defs.getStr("echo_ParsedEntityWrap");
if(null!=S)setParsedEntityWrap(S);
S=defs.getStr("echo_validation"); // "true" or "false"
if(null!=S)setValidation((new Boolean(S)).booleanValue());
}
public void doIt(String inputFileName) throws IOException{
InputSource input;
try {
if(null==out){
out=new PrintWriter(new OutputStreamWriter(System.out, "UTF8"));
defs.put("echo_out",out);
}
input=Resolver.createInputSource(new File(inputFileName));
Parser parser=ParserFactory.makeParser(parserName);
parser.setDocumentHandler(this);
parser.setErrorHandler( new EchoErrorHandler() );
parser.parse (input);
} catch (SAXParseException err) {
lg.logIt("** Parsing error"
+ ", line " + err.getLineNumber ()
+ ", uri " + err.getSystemId ());
lg.logIt(" " + err.getMessage ());
// Unpack the delivered exception to get the exception it contains
Exception x = err;
if (err.getException() != null)x = err.getException();
x.printStackTrace ();
} catch (SAXException e) {
Exception x = e;
if (e.getException() != null)x = e.getException();
lg.logIt("Error in EchoAsHtml.doIt()",x);
} catch (Throwable t) {
lg.logIt("Error in EchoAsHtml.doIt()",t);
}
}
class EchoErrorHandler extends HandlerBase{
public void error (SAXParseException e)throws SAXParseException{
try{
lg.logIt("passalong error",e);
nl();e.printStackTrace(out);
}catch(Exception ex){}
throw e;
}
// dump warnings too
public void warning (SAXParseException err)throws SAXParseException{
try{nl();err.printStackTrace(out);}catch(Exception ex){}
lg.logIt("** Warning"
+ ", line " + err.getLineNumber()
+ ", uri " + err.getSystemId());
lg.logIt(" " + err.getMessage());
}
}
//===========================================================
// SAX DocumentHandler methods
//===========================================================
public void setDocumentLocator (Locator L){
// Save this to resolve relative URIs or to give diagnostics.
defs.put("echo_locator",L.getSystemId());
}
public void startDocument () throws SAXException{
out.println("<?xml version='1.0' encoding='UTF-8'?>");
out.println("<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'");
out.println("'http://www.w3.org/TR/xhtml1/DTD/strict.dtd'>");
out.println("<html xmlns='http://www.w3.org/TR/xhtml1/strict' xml:lang='en' lang='en'>");
String hd=defs.getStr("echo_head");
if(null==hd){
out.print("<head><title> ");
out.print(inputFileName);
out.println(" </title></head>");
}else out.println(hd);
out.println("<body>");
}
// <head><style> .arithexp {color:blue} </style></head>
public void endDocument ()throws SAXException{
out.println("</body></html>");
out.flush ();
}
public void startElement (String name, AttributeList attrs)
throws SAXException{
indentLevel++;
// emit ("ELEMENT: ");
String tag=defs.getStr(name);
if(null==tag)tag="span";
StringBuffer buff=new StringBuffer();
nl(buff);
buff.append("<");
buff.append(tag);
buff.append(" class=\'");
buff.append(name);
buff.append("\'");
if(null!=attrs && 0<attrs.getLength())startAttrs(attrs,buff);
buff.append(">"); out.print(buff);
}
public void startAttrs(AttributeList attrs,StringBuffer buff)
throws SAXException{
for(int i=0;i<attrs.getLength();i++){
String name=attrs.getName(i);
String val=attrs.getValue(i);
if(!"xtag".equals(name)){
nl(buff);
buff.append(name);
buff.append("=\'");
buff.append(val);
buff.append("\'");
}else{
i++;
if(i>=attrs.getLength()||!"htag".equals(attrs.getName(i)))
throw new SAXException("xtag "+val+" with no matching htag");
defs.put(val,attrs.getValue(i));
// lg.logIt("added "+val+" => "+attrs.getValue(i));
}
}
nl(buff);
}
public void endElement (String name) throws SAXException{
StringBuffer B=new StringBuffer();
nl(B);
String endTag=defs.getStr(name);
if(null==endTag)endTag="span";
B.append("</");B.append(endTag);B.append(">");
out.print(B);
indentLevel--;
}
public void characters (char buff[], int offset, int len)
throws SAXException{
nl();
out.write(buff,offset,len);
}
public void ignorableWhitespace (char buf [], int offset, int len)
throws SAXException{ // ignore it
}
public void processingInstruction (String target, String data)
throws SAXException{
// nl();
lg.logIt("PROCESS: "+target+"("+data+")");
// emit ("<?"+target+" "+data+"?>");
/* Just for fun, we assume that the target is a classname with
a no-argument constructor (if data is empty) or a String
constructor (if data non-empty) */
try{
Class C=Class.forName(target);
boolean empty=(null==data || 0==data.trim().length());
if(!empty){
Class[]paramTypes={Class.forName("java.lang.String"),
Class.forName("MyNa.utils.Env")};
Object[]paramVals={data,defs};
lg.logIt("looking for constructor (String,Env)");
Constructor cons=C.getConstructor(paramTypes);
Object ob=cons.newInstance(paramVals);
}else{
Class[]paramTypes={Class.forName("MyNa.utils.Env")};
Object[]paramVals={defs};
lg.logIt("looking for constructor (Env)");
Constructor cons=C.getConstructor(paramTypes);
Object ob=cons.newInstance(paramVals);
}
// all processing to be done by the constructor itself
}catch(Exception ex){lg.logIt("error in processing inst",ex);}
}
//===========================================================
// LexicalEventListener methods
//===========================================================
public void comment(java.lang.String text) throws SAXException{
nl(); out.write("<!-- "); out.write(text); out.println("-->");
}
public void startCDATA() throws SAXException{
inCDATA=true;
lg.logIt("startCDATA with "+cDATAWrap);
if(null!=cDATAWrap && cDATAWrap.length()>0){
nl();out.write("<"); out.write(cDATAWrap); out.write(">");
}
}
public void endCDATA() throws SAXException{
inCDATA=false;
if(null!=cDATAWrap && cDATAWrap.length()>0){
out.write("</"); out.write(cDATAWrap); out.write(">");
}
}
public void startParsedEntity(java.lang.String name)
throws SAXException{
inParsedEntity=true;
lg.logIt("startParsedEntity with "+parsedEntityWrap);
if(null!=parsedEntityWrap && parsedEntityWrap.length()>0){
nl();out.write("<"); out.write(parsedEntityWrap); out.write(">");
}
lg.logIt("in parsed Entity: "+name);
}
public void endParsedEntity(java.lang.String name,
boolean included)
throws SAXException{
inParsedEntity=false;
if(null!=parsedEntityWrap && parsedEntityWrap.length()>0){
out.write("</"); out.write(parsedEntityWrap); out.write(">");
}
lg.logIt("exit ParsedEntity "+name+", included="+included);
}
//===========================================================
// Helpers ...
//===========================================================
// Wrap I/O exceptions in SAX exceptions, to
// suit handler signature requirements
private void emit (String s) throws SAXException{
out.write (s);
out.flush ();
}
// Start a new line
// and indent the next line appropriately
private void nl()throws SAXException{
if(inCDATA || inParsedEntity)return;
out.write (lineEnd);
for (int i=0; i < indentLevel; i++) out.write(indentSpace);
}
private void nl(StringBuffer B)throws SAXException{
if(inCDATA || inParsedEntity)return;
B.append(lineEnd);
for (int i=0; i < indentLevel; i++)B.append(indentSpace);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -