⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xsltranslator.java

📁 A framework written in Java for implementing high-level and dynamic languages, compiling them into J
💻 JAVA
字号:
// Copyright (c) 2002, 2003  Per M.A. Bothner.// This is free software;  for terms and warranty disclaimer see ./COPYING.package gnu.kawa.xslt;import gnu.lists.*;import gnu.math.*;import gnu.bytecode.*;import gnu.expr.*;import gnu.text.*;import gnu.mapping.*;import java.util.Stack;import gnu.xml.*;import gnu.kawa.xml.*;import gnu.xquery.lang.*;import gnu.kawa.functions.AppendValues;/** Translate an XSLT stylesheet to a Kawa Expression tree. */public class XslTranslator extends Lexer implements Consumer{  boolean inTemplate;  Declaration consumerDecl;  StringBuffer nesting = new StringBuffer(100);  ModuleExp mexp;  Compilation comp;  /** We seen a startAttribute but not the closing endAttribute. */  boolean inAttribute;  /** The 'attribute type' from the most recent startAttribute. */  Object attributeType;  /** Buffer to acumulate the value of the current attribute. */  StringBuffer attributeValue = new StringBuffer(100);  XSLT interpreter;  InPort in;  /** Non-null if we're inside an xsl:template. */  LambdaExp templateLambda;  XslTranslator(InPort inp, gnu.text.SourceMessages messages,		XSLT interpreter)  {    super(inp, messages);    this.interpreter = interpreter;    this.in = inp;  }  static final String XSL_TRANSFORM_URI  = "http://www.w3.org/1999/XSL/Transform";  public String popMatchingAttribute(String ns, String name, int start)  {    int size = comp.exprStack.size();    for (int i = start; i < size;  i++)      {	Object el = comp.exprStack.elementAt(start);	if (! (el instanceof ApplyExp))	  return null;	ApplyExp aexp = (ApplyExp) el;	Expression function = aexp.getFunction();	if (aexp.getFunction() != MakeAttribute.makeAttributeExp)	  return null;	Expression[] args = aexp.getArgs();	if (args.length != 2)	  return null;	Expression arg0 = args[0];	if (! (arg0 instanceof QuoteExp))	  return null;	Object tag = ((QuoteExp) arg0).getValue();	if (! (tag instanceof Symbol))	  return null;	Symbol stag = (Symbol) tag;	if (stag.getLocalPart() == name && stag.getNamespaceURI() == ns)	  {	    comp.exprStack.removeElementAt(i);	    return (String) ((QuoteExp) args[1]).getValue();	  }      }    return null;  }  Expression popTemplateBody(int start)  {    // should strip off attributes?    int i = comp.exprStack.size() - start;    Expression exp;    Expression[] args = new Expression[i];    while (--i >= 0)      args[i] = (Expression) comp.exprStack.pop();    return new ApplyExp(AppendValues.appendValues, args);  }  public static String isXslTag (Object type)  {    if (type instanceof QuoteExp)      type = ((QuoteExp) type).getValue();    if (! (type instanceof Symbol))      return null;    Symbol qname = (Symbol) type;    if (qname.getNamespaceURI() != XSL_TRANSFORM_URI)      return null;    return qname.getLocalName();  }  void append(Expression expr)  {    // FIXME  }  public void startElement (Object type)  {     String xslTag = isXslTag(type);    if (xslTag == "template")      {	if (templateLambda != null)	  error("nested xsl:template");	templateLambda = new LambdaExp();	//templateLambda.setFile(getName());	//templateLambda.setLine(declLine, declColumn);      }    if (type instanceof XName)      {	// This gets rid of namespace "nodes".   That's not really right.	// We do want to get rid of xmlns:xsl, though, at least.  FIXME.	XName xn = (XName) type;	type = Symbol.make(xn.getNamespaceURI(), xn.getLocalPart(),                           xn.getPrefix());      }    nesting.append((char) comp.exprStack.size());    push(type);  }  public void startAttribute (Object attrType)  {    if (inAttribute)      error('f', "internal error - attribute inside attribute");    attributeType = attrType;    attributeValue.setLength(0);    nesting.append((char) comp.exprStack.size());    inAttribute = true;  }  public void endAttribute()  {    Expression[] args = new Expression[2];    args[0] = new QuoteExp(attributeType);    args[1] = new QuoteExp(attributeValue.toString());    push(new ApplyExp(MakeAttribute.makeAttributeExp, args));    nesting.setLength(nesting.length()-1);    inAttribute = false;  }  public void endElement ()  {    int nlen = nesting.length()-1;    int start = nesting.charAt(nlen);    nesting.setLength(nlen);    Expression startTag = (Expression) comp.exprStack.elementAt(start);    String xslTag = isXslTag(startTag);    if (xslTag == "value-of")      {	String select = popMatchingAttribute("", "select", start + 1);	if (select != null)	  {	    Expression exp = interpreter.parseXPath(select, getMessages());	    exp = new ApplyExp(ClassType.make("gnu.xml.TextUtils")                               .getDeclaredMethod("stringValue", 1),                               new Expression[] { exp });	    comp.exprStack.pop();	    push(exp);	    return;	  }      }    else if (xslTag == "apply-templates")      {	String select = popMatchingAttribute("", "select", start + 1);	String mode = popMatchingAttribute("", "mode", start + 1);	Expression[] args	  = { new QuoteExp(select), resolveQNameExpression(mode) };	comp.exprStack.pop();	push(new ApplyExp(new QuoteExp(applyTemplatesProc), args));      }    else if (xslTag == "if")      {	String select = popMatchingAttribute("", "test", start + 1);	Expression test = interpreter.parseXPath(select, getMessages());	test = XQParser.booleanValue(test);	Expression clause = popTemplateBody(start+1);	comp.exprStack.pop();	push(new IfExp(test, clause, QuoteExp.voidExp));      }    else if (xslTag == "stylesheet" || xslTag == "transform")      {	push(new ApplyExp(new QuoteExp(runStylesheetProc),			  Expression.noExpressions));	Expression body = popTemplateBody(start+1);	push(body);	mexp.body = body;      }    else if (xslTag == "template")      {	String match = popMatchingAttribute("", "match", start + 1);	String name = popMatchingAttribute("", "name", start + 1);	String priority = popMatchingAttribute("", "priority", start + 1);	String mode = popMatchingAttribute("", "mode", start + 1);	templateLambda.body = popTemplateBody(start+1);	comp.exprStack.pop();	Expression[] args = new Expression[5];	double prio = 0.0; // FIXME	args[0] = resolveQNameExpression(name);	args[1] = new QuoteExp(match);	args[2] = new QuoteExp(DFloNum.make(prio));	args[3] = resolveQNameExpression(mode);	args[4] = templateLambda;	push(new ApplyExp(new QuoteExp(defineTemplateProc), args));	templateLambda = null;      }    else      {	Expression[] args = new Expression[comp.exprStack.size() - start];	for (int i = args.length;  --i >= 0; )	  args[i] = (Expression) comp.exprStack.pop();	// FIXME does not preserve namespace attributes.	Expression exp = new ApplyExp(MakeElement.makeElement, args);	push(exp);	mexp.body = exp;      }  }  public void write (int v)  {    if (inAttribute)      {        /* #ifdef JAVA5 */        // attributeValue.appendCodePoint(v);        /* #else */        attributeValue.append((char) v);        /* #endif */      }    else      {        String str;        if (v < 0x10000)          str = String.valueOf(v);        else          { // Use surrogates.            char[] c2 = { (char) (((v - 0x10000) >> 10) + 0xD800),                          (char) ((v & 0x3FF) + 0xDC00) };            str = new String(c2);          }        push(str);      }  }  /* #ifdef JAVA5 */  // public Consumer append (char v)  // {  //   if (inAttribute)  //     attributeValue.append(v);  //   else  //     push(String.valueOf(v));  //   return this;  // }  // public Consumer append (CharSequence csq)  // {  //   if (inAttribute)  //     attributeValue.append(csq);  //   else  //     push(csq.toString());  //   return this;  // }  // public Consumer append (CharSequence csq, int start, int end)  // {  //   return append(csq.subSequence(start, end));  // }  /* #else */  public Consumer append (String str)  {    if (inAttribute)      attributeValue.append(str);    else      push(str);    return this;  }  /* #endif */  void push(Expression exp)  {    comp.exprStack.push(exp);  }  void push(Object value)  {    push(new QuoteExp(value));  }  public void writeBoolean(boolean v)  {    if (inAttribute)      attributeValue.append(v);    else      push(v ? QuoteExp.trueExp : QuoteExp.falseExp);  }  public void writeFloat(float v)  {    if (inAttribute)      attributeValue.append(v);    else      push(DFloNum.make(v));  }  public void writeDouble(double v)  {    if (inAttribute)      attributeValue.append(v);    else      push(DFloNum.make(v));  }  public void writeInt(int v)  {    if (inAttribute)      attributeValue.append(v);    else      push(IntNum.make(v));  }  public void writeLong(long v)  {     if (inAttribute)      attributeValue.append(v);    else      push(IntNum.make(v));  }  public void startDocument()  {      }  public void startDocument(ModuleExp mexp)  {    this.mexp = mexp;    startDocument();  }  public void endDocument()  {  }  public void writeObject(Object v)  {    if (inAttribute)      attributeValue.append(v);    else      push(v);  }  public void write(char[] buf, int off, int len)  {    if (inAttribute)      attributeValue.append(buf, off, len);    else      push(new String(buf, off, len));  }  public void write (String str)  {    if (inAttribute)      attributeValue.append(str);    else      push(str);  }  /* #ifdef use:java.lang.CharSequence */  public void write (CharSequence str, int start, int length)  {    write(str.subSequence(start, length).toString());  }  /* #else */  // public void write (String str, int start, int length)  // {  //   write(str.substring(start, length));  // }  /* #endif */  public boolean ignoring()  {    return false;  }  public Expression getExpression()  {    return (Expression) comp.exprStack.pop();  }  public void error (char kind, String message)  {    getMessages().error(kind, message);  }  /*  public void fatal(String message) throws SyntaxException  {    getMessages().error('f', message);    throw new SyntaxException(getMessages());  }  */  Expression resolveQNameExpression(String name)  {    if (name == null)      return QuoteExp.nullExp;    else      return new QuoteExp(Symbol.make(null, name)); // FIXME  }  public void parse (Compilation comp)    throws java.io.IOException  {    this.comp = comp;    if (comp.exprStack == null)      comp.exprStack = new Stack();    ModuleExp mexp = comp.pushNewModule(this);    comp.mustCompileHere();    startDocument(mexp);    XMLParser.parse(in, getMessages(), this);    endDocument();    comp.pop(mexp);  }  static final ClassType typeXSLT    = gnu.bytecode.ClassType.make("gnu.kawa.xslt.XSLT");  static final ClassType typeTemplateTable    = gnu.bytecode.ClassType.make("gnu.kawa.xslt.TemplateTable");  static final Method defineTemplateMethod    = typeXSLT.getDeclaredMethod("defineTemplate", 5);  static final Method runStylesheetMethod    = typeXSLT.getDeclaredMethod("runStylesheet", 0);  static final PrimProcedure defineTemplateProc    = new PrimProcedure(defineTemplateMethod);  static final PrimProcedure runStylesheetProc    = new PrimProcedure(runStylesheetMethod);  static final Method applyTemplatesMethod    = typeXSLT.getDeclaredMethod("applyTemplates", 2);  static final PrimProcedure applyTemplatesProc    = new PrimProcedure(applyTemplatesMethod);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -