xslparser.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,584 行 · 第 1/3 页

JAVA
1,584
字号
    }    else if (cb.matches("amp")) {      addText('&');      return read();    }    else if (cb.matches("quot")) {      addText('"');      return read();    }    else if (cb.matches("apos")) {      addText('\'');      return read();    }    else {      addText('&');      addText(cb.close());    }    return ch;  }  /**   * Parses the contents of a '<#' section.   */  private int parseScriptlet(Node parent)    throws IOException, XslParseException  {    String filename = is.getUserPath();    int line = this.line;    int ch = read();    QNode node;    if (ch == '=') {      node = (QNode) xsl.createElementNS(XTPNS, "xtp:expression");      ch = read();    }    else if (ch == '!') {      node = (QNode) xsl.createElementNS(XTPNS, "xtp:declaration");      ch = read();    }    else if (ch == '@') {      parseDirective(parent);      return read();    } else      node = (QNode) xsl.createElementNS(XTPNS, "xtp:scriptlet");    node.setLocation(is.getURL(), is.getUserPath(), line, 0);    parent.appendChild(node);    text.clear();    while (ch >= 0) {      if (ch == '#') {	ch = read();	if (ch == '>')	  break;	else	  addText('#');      } else {	addText((char) ch);	ch = read();      }    }    node.appendChild(xsl.createTextNode(text.toString()));    text.clear();    return read();  }  /**   * parses an xtp directive: <#@   */  private void parseDirective(Node parent)    throws IOException, XslParseException  {    int ch;    ch = skipWhitespace(read());    ch = readTag(ch);    String name = tag.toString();    if (! name.equals("page") && ! name.equals("cache"))      throw error(L.l("unknown directive `{0}'", name));    QElement elt = (QElement) xsl.createElementNS(XTPNS, "xtp:directive." + name);    elt.setLocation(is.getURL(), is.getUserPath(), line, 0);    parent.appendChild(elt);    ch = parseAttributes(parent, elt, ch, true);    if (ch != '#')      throw error(L.l("expected `{0}' at {1}", "#", badChar(ch)));    if ((ch = read()) != '>')      throw error(L.l("expected `{0}' at {1}", ">", badChar(ch)));    if (name.equals("page")) {      String contentType = elt.getAttribute("contentType");      if (! contentType.equals(""))	parseContentType(parent, contentType);    }  }    private int parseStatement(Node parent, int ch)    throws IOException, XslParseException  {    ch = skipWhitespace(ch);    if (ch == '$') {      ch = read();            if (XmlChar.isNameStart(ch)) {        String name = parseName(ch);        return parseExtension(parent, name);      }      else if (ch == '(') {        Element elt = xsl.createElementNS(XSLNS, "xsl:value-of");        CharBuffer test = CharBuffer.allocate();        lexToRparen(test);        elt.setAttribute("select", test.close());        parent.appendChild(elt);        return read();      }      else        throw error(L.l("expected statement at {0}", badChar(ch)));    }    else if (ch == '<') {      parseBlock(parent, ch);      return read();    }    else if (ch == ';')      return read();    else      throw error(L.l("expected statement at {0}", badChar(ch)));  }  private int parseExtension(Node parent, String name)    throws IOException, XslParseException  {    int ch = read();    if (name.equals("if"))      return parseIf(parent, ch);    String arg = (String) _xslCommands.get(name);    if (arg != null) {      QElement elt = (QElement) xsl.createElementNS(XSLNS, "xsl:" + name);      elt.setLocation(is.getURL(), is.getUserPath(), line, 0);      parent.appendChild(elt);      ch = skipWhitespace(ch);      if (ch == '(') {        parseArgs(elt, arg);        ch = skipWhitespace(read());      }            return parseStatement(elt, ch);    }    arg = (String) _xtpCommands.get(name);    if (arg != null) {      QElement elt = (QElement) xsl.createElement("xtp:" + name);      elt.setLocation(is.getURL(), is.getUserPath(), line, 0);      parent.appendChild(elt);      ch = skipWhitespace(ch);      if (ch == '(') {        parseArgs(elt, arg);        ch = skipWhitespace(read());      }            return parseStatement(elt, ch);    }        ch = skipWhitespace(ch);          if (ch == '=') {      QElement elt = (QElement) xsl.createElement("xtp:assign");      elt.setLocation(is.getURL(), is.getUserPath(), line, 0);      elt.setAttribute("name", name.intern());      parent.appendChild(elt);      ch = skipWhitespace(read());      if (ch != '$')        return parseStatement(elt, ch);      else if ((ch = read()) != '(') {        peek = ch;        return parseStatement(elt, ch);      }      else {        CharBuffer test = CharBuffer.allocate();        lexToRparen(test);        elt.setAttribute("select", test.close());        return read();      }    }    QElement elt = (QElement) xsl.createElement(name);    elt.setLocation(is.getURL(), is.getUserPath(), line, 0);    parent.appendChild(elt);    if (ch == '(') {      parseArgs(elt, arg);      ch = skipWhitespace(read());    }          return parseStatement(elt, ch);  }  private int parseIf(Node parent, int ch)    throws IOException, XslParseException  {    QElement choose = (QElement) xsl.createElementNS(XSLNS, "xsl:choose");    choose.setLocation(is.getURL(), is.getUserPath(), line, 0);    parent.appendChild(choose);    while (true) {      lexExpect(ch, '(');      CharBuffer test = CharBuffer.allocate();      lexToRparen(test);      QElement elt = (QElement) xsl.createElementNS(XSLNS, "xsl:when");      choose.appendChild(elt);      elt.setLocation(is.getURL(), is.getUserPath(), line, 0);      elt.setAttribute("test", test.close());      ch = parseStatement(elt, skipWhitespace(read()));      ch = skipWhitespace(ch);      if (ch != '$')        return ch;      ch = read();      if (! XmlChar.isNameStart(ch)) {        peek = ch;        return '$';      }            String name = parseName(ch);      if (! name.equals("else"))        return parseExtension(parent, name);            ch = skipWhitespace(read());      if (ch == '<') {        elt = (QElement) xsl.createElementNS(XSLNS, "xsl:otherwise");        choose.appendChild(elt);        elt.setLocation(is.getURL(), is.getUserPath(), line, 0);                return parseStatement(elt, skipWhitespace(ch));      }      name = parseName(read());      if (! name.equals("if"))        throw error(L.l("expected $if at `${0}'", name));      ch = read();    }  }  private String parseName(int ch)    throws IOException, XslParseException  {    CharBuffer cb = CharBuffer.allocate();    for (; XmlChar.isNameChar(ch); ch = read())      cb.append((char) ch);    peek = ch;    return cb.close();  }  private void parseArgs(Element elt, String arg)    throws IOException, XslParseException  {    CharBuffer cb = CharBuffer.allocate();    String key = null;    boolean isFirst = true;    int ch;        for (ch = read(); ch >= 0 && ch != ')'; ch = read()) {      cb.append((char) ch);            switch (ch) {      case '(':        lexToRparen(cb);        cb.append(')');        break;      case '"': case '\'':        lexString(cb, ch);        break;              case '=':        ch = read();        if (ch == '>') {          cb.setLength(cb.length() - 1);          key = cb.toString().trim();          cb.clear();        }        else {          peek = ch;        }        break;              case ',':        cb.setLength(cb.length() - 1);        if (key != null)          elt.setAttribute(key, cb.toString());        else if (arg != null && isFirst)          elt.setAttribute(arg, cb.toString());        else          throw error(L.l("unexpected arg `{0}'", cb));        cb.clear();        isFirst = false;        key = null;        break;      }    }    if (ch != ')')      throw error(L.l("expected `{0}' at {1}", ")", badChar(ch)));    if (key != null)      elt.setAttribute(key, cb.close());    else if (arg != null && cb.length() > 0 && isFirst)      elt.setAttribute(arg, cb.close());    else if (cb.length() > 0)      throw error(L.l("unexpected arg `{0}'", cb));  }  /**   * Scan the buffer up to the right parenthesis.   *   * @param cb buffer holding the contents.   */  private void lexToRparen(CharBuffer cb)    throws IOException, XslParseException  {    String filename = getFilename();    int line = getLine();    int ch;        for (ch = read(); ch >= 0 && ch != ')'; ch = read()) {      cb.append((char) ch);            switch (ch) {      case '(':        lexToRparen(cb);        cb.append(')');        break;      case '"': case '\'':        lexString(cb, ch);        break;      }    }    if (ch != ')')      throw error(L.l("expected `{0}' at {1}.  Open at {2}",                      ")", badChar(ch), filename + ":" + line));  }  private void lexString(CharBuffer cb, int end)    throws IOException, XslParseException  {    int ch;        for (ch = read(); ch >= 0 && ch != end; ch = read()) {      cb.append((char) ch);    }    if (ch != end)      throw error(L.l("expected `{0}' at {1}", "" + (char) end, badChar(ch)));    cb.append((char) end);  }  private void lexExpect(int ch, int match)    throws IOException, XslParseException  {    for (; XmlChar.isWhitespace((char) ch); ch = read()) {    }    if (ch != match)      throw error(L.l("expected `{0}' at {1}",                      "" + (char) match, badChar(ch)));  }  private CharScanner wsScanner = new CharScanner(" \t");  private CharScanner delimScanner = new CharScanner(" \t;=");  /**   * parse the content-type, possibly changing character-encoding.   */  private void parseContentType(Node parent, String contentType)    throws IOException, XslParseException  {    CharCursor cursor = new StringCharCursor(contentType);    CharBuffer buf = new CharBuffer();    wsScanner.skip(cursor);    delimScanner.scan(cursor, buf);    if (buf.length() <= 0)      return;    Element output = xsl.createElementNS(XSLNS, "xsl:output");    parent.appendChild(output);    output.setAttribute("media-type", buf.toString());    delimScanner.skip(cursor);    buf.clear();    delimScanner.scan(cursor, buf);    wsScanner.skip(cursor);    if (cursor.current() == '=' && buf.toString().equals("charset")) {      delimScanner.skip(cursor);      buf.clear();      delimScanner.scan(cursor, buf);      if (buf.length() > 0) {	output.setAttribute("encoding", Encoding.getMimeName(buf.toString()));	is.setEncoding(buf.toString());      }    }  }  /**   * Parses the attributes of an element.   *   * @param parent the elements parent.   * @param elt the element itself   * @param ch the next character   * @param isDirective true if this is a special directive   *   * @return the next character   */  private int parseAttributes(Node parent, Element elt,                              int ch, boolean isDirective)    throws IOException, XslParseException  {    HashMap<String,String> newNamespaces = null;        ch = skipWhitespace(ch);    while (XmlChar.isNameStart(ch)) {      ch = readTag(ch);      String name = tag.toString();      ch = skipWhitespace(ch);      String value = null;      if (ch == '=') {	ch = skipWhitespace(read());	ch = readValue(ch);	ch = skipWhitespace(ch);        value = tag.toString();      }      int p;      if (isDirective && name.equals("import")) {        Element copy = (Element) elt.cloneNode(false);	copy.setAttribute(name, value);        parent.appendChild(copy);      }      else if (name.startsWith("xmlns")) {        QElement qElt = (QElement) elt;        if (newNamespaces == null) {          newNamespaces = new HashMap<String,String>(_namespaces);          _namespaces = newNamespaces;        }        String prefix;        if (name.startsWith("xmlns:"))          prefix = name.substring(6);        else          prefix = "";        _namespaces.put(prefix, value);        qElt.setAttributeNS(XMLNS, name, value);        // backpatch if modify own name        if (prefix != "" && qElt.getNodeName().startsWith(prefix)) {          QDocument doc = (QDocument) xsl;          QName newName = doc.createName(value, qElt.getNodeName());          qElt.setName(newName);        }      }      else if ((p = name.indexOf(':')) >= 0) {        String prefix = name.substring(0, p);        String uri = _namespaces.get(prefix);        if (uri != null) {          QElement qElt = (QElement) elt;          qElt.setAttributeNS(uri, name, value);        }        else          elt.setAttribute(name, value);      }      else {	elt.setAttribute(name, value);      }    }    return ch;  }  /**   * Parses a processing instruction   */  private ProcessingInstruction parsePi()    throws IOException, XslParseException  {    int ch = read();    if (! XmlChar.isNameStart(ch))      throw error(L.l("expected name at {0}", badChar(ch)));    ch = readTag(ch);    String name = tag.toString();    text.clear();    while (ch >= 0) {      if (ch == '?') {

⌨️ 快捷键说明

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