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 + -
显示快捷键?