📄 parser.java
字号:
ErrorMsg err = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, node); reportError(ERROR, err); } catch (Exception e) { ErrorMsg err = new ErrorMsg(ErrorMsg.INTERNAL_ERR, e.getMessage(), node); reportError(FATAL, err); } } else { if (uri != null) { // Check if the element belongs in our namespace if (uri.equals(XSLT_URI)) { node = new UnsupportedElement(uri, prefix, local, false); UnsupportedElement element = (UnsupportedElement)node; ErrorMsg msg = new ErrorMsg(ErrorMsg.UNSUPPORTED_XSL_ERR, getLineNumber(),local); element.setErrorMessage(msg); if (versionIsOne) { reportError(UNSUPPORTED,msg); } } // Check if this is an XSLTC extension element else if (uri.equals(TRANSLET_URI)) { node = new UnsupportedElement(uri, prefix, local, true); UnsupportedElement element = (UnsupportedElement)node; ErrorMsg msg = new ErrorMsg(ErrorMsg.UNSUPPORTED_EXT_ERR, getLineNumber(),local); element.setErrorMessage(msg); } // Check if this is an extension of some other XSLT processor else { Stylesheet sheet = _xsltc.getStylesheet(); if ((sheet != null) && (sheet.isExtension(uri))) { if (sheet != (SyntaxTreeNode)_parentStack.peek()) { node = new UnsupportedElement(uri, prefix, local, true); UnsupportedElement elem = (UnsupportedElement)node; ErrorMsg msg = new ErrorMsg(ErrorMsg.UNSUPPORTED_EXT_ERR, getLineNumber(), prefix+":"+local); elem.setErrorMessage(msg); } } } } if (node == null) { node = new LiteralElement(); node.setLineNumber(getLineNumber()); } } if ((node != null) && (node instanceof LiteralElement)) { ((LiteralElement)node).setQName(qname); } return(node); } /** * checks the list of attributes against a list of allowed attributes * for a particular element node. */ private void checkForSuperfluousAttributes(SyntaxTreeNode node, Attributes attrs) { QName qname = node.getQName(); boolean isStylesheet = (node instanceof Stylesheet); String[] legal = (String[]) _instructionAttrs.get(qname); if (versionIsOne && legal != null) { int j; final int n = attrs.getLength(); for (int i = 0; i < n; i++) { final String attrQName = attrs.getQName(i); if (isStylesheet && attrQName.equals("version")) { versionIsOne = attrs.getValue(i).equals("1.0"); } // Ignore if special or if it has a prefix if (attrQName.startsWith("xml") || attrQName.indexOf(':') > 0) continue; for (j = 0; j < legal.length; j++) { if (attrQName.equalsIgnoreCase(legal[j])) { break; } } if (j == legal.length) { final ErrorMsg err = new ErrorMsg(ErrorMsg.ILLEGAL_ATTRIBUTE_ERR, attrQName, node); // Workaround for the TCK failure ErrorListener.errorTests.error001.. err.setWarningError(true); reportError(WARNING, err); } } } } /** * Parse an XPath expression: * @param parent - XSL element where the expression occured * @param exp - textual representation of the expression */ public Expression parseExpression(SyntaxTreeNode parent, String exp) { return (Expression)parseTopLevel(parent, "<EXPRESSION>"+exp, null); } /** * Parse an XPath expression: * @param parent - XSL element where the expression occured * @param attr - name of this element's attribute to get expression from * @param def - default expression (if the attribute was not found) */ public Expression parseExpression(SyntaxTreeNode parent, String attr, String def) { // Get the textual representation of the expression (if any) String exp = parent.getAttribute(attr); // Use the default expression if none was found if ((exp.length() == 0) && (def != null)) exp = def; // Invoke the XPath parser return (Expression)parseTopLevel(parent, "<EXPRESSION>"+exp, exp); } /** * Parse an XPath pattern: * @param parent - XSL element where the pattern occured * @param pattern - textual representation of the pattern */ public Pattern parsePattern(SyntaxTreeNode parent, String pattern) { return (Pattern)parseTopLevel(parent, "<PATTERN>"+pattern, pattern); } /** * Parse an XPath pattern: * @param parent - XSL element where the pattern occured * @param attr - name of this element's attribute to get pattern from * @param def - default pattern (if the attribute was not found) */ public Pattern parsePattern(SyntaxTreeNode parent, String attr, String def) { // Get the textual representation of the pattern (if any) String pattern = parent.getAttribute(attr); // Use the default pattern if none was found if ((pattern.length() == 0) && (def != null)) pattern = def; // Invoke the XPath parser return (Pattern)parseTopLevel(parent, "<PATTERN>"+pattern, pattern); } /** * Parse an XPath expression or pattern using the generated XPathParser * The method will return a Dummy node if the XPath parser fails. */ private SyntaxTreeNode parseTopLevel(SyntaxTreeNode parent, String text, String expression) { int line = getLineNumber(); try { _xpathParser.setScanner(new XPathLexer(new StringReader(text))); Symbol result = _xpathParser.parse(expression, line); if (result != null) { final SyntaxTreeNode node = (SyntaxTreeNode)result.value; if (node != null) { node.setParser(this); node.setParent(parent); node.setLineNumber(line);// System.out.println("e = " + text + " " + node); return node; } } reportError(ERROR, new ErrorMsg(ErrorMsg.XPATH_PARSER_ERR, expression, parent)); } catch (Exception e) { if (_xsltc.debug()) e.printStackTrace(); reportError(ERROR, new ErrorMsg(ErrorMsg.XPATH_PARSER_ERR, expression, parent)); } // Return a dummy pattern (which is an expression) SyntaxTreeNode.Dummy.setParser(this); return SyntaxTreeNode.Dummy; } /************************ ERROR HANDLING SECTION ************************/ /** * Returns true if there were any errors during compilation */ public boolean errorsFound() { return _errors.size() > 0; } /** * Prints all compile-time errors */ public void printErrors() { final int size = _errors.size(); if (size > 0) { System.err.println(new ErrorMsg(ErrorMsg.COMPILER_ERROR_KEY)); for (int i = 0; i < size; i++) { System.err.println(" " + _errors.elementAt(i)); } } } /** * Prints all compile-time warnings */ public void printWarnings() { final int size = _warnings.size(); if (size > 0) { System.err.println(new ErrorMsg(ErrorMsg.COMPILER_WARNING_KEY)); for (int i = 0; i < size; i++) { System.err.println(" " + _warnings.elementAt(i)); } } } /** * Common error/warning message handler */ public void reportError(final int category, final ErrorMsg error) { switch (category) { case Constants.INTERNAL: // Unexpected internal errors, such as null-ptr exceptions, etc. // Immediately terminates compilation, no translet produced _errors.addElement(error); break; case Constants.UNSUPPORTED: // XSLT elements that are not implemented and unsupported ext. // Immediately terminates compilation, no translet produced _errors.addElement(error); break; case Constants.FATAL: // Fatal error in the stylesheet input (parsing or content) // Immediately terminates compilation, no translet produced _errors.addElement(error); break; case Constants.ERROR: // Other error in the stylesheet input (parsing or content) // Does not terminate compilation, no translet produced _errors.addElement(error); break; case Constants.WARNING: // Other error in the stylesheet input (content errors only) // Does not terminate compilation, a translet is produced _warnings.addElement(error); break; } } public Vector getErrors() { return _errors; } public Vector getWarnings() { return _warnings; } /************************ SAX2 ContentHandler INTERFACE *****************/ private Stack _parentStack = null; private Hashtable _prefixMapping = null; /** * SAX2: Receive notification of the beginning of a document. */ public void startDocument() { _root = null; _target = null; _prefixMapping = null; _parentStack = new Stack(); } /** * SAX2: Receive notification of the end of a document. */ public void endDocument() { } /** * SAX2: Begin the scope of a prefix-URI Namespace mapping. * This has to be passed on to the symbol table! */ public void startPrefixMapping(String prefix, String uri) { if (_prefixMapping == null) { _prefixMapping = new Hashtable(); } _prefixMapping.put(prefix, uri); } /** * SAX2: End the scope of a prefix-URI Namespace mapping. * This has to be passed on to the symbol table! */ public void endPrefixMapping(String prefix) { } /** * SAX2: Receive notification of the beginning of an element. * The parser may re-use the attribute list that we're passed so * we clone the attributes in our own Attributes implementation */ public void startElement(String uri, String localname, String qname, Attributes attributes) throws SAXException { final int col = qname.lastIndexOf(':'); final String prefix = (col == -1) ? null : qname.substring(0, col); SyntaxTreeNode element = makeInstance(uri, prefix, localname, attributes); if (element == null) { ErrorMsg err = new ErrorMsg(ErrorMsg.ELEMENT_PARSE_ERR, prefix+':'+localname); throw new SAXException(err.toString()); } // If this is the root element of the XML document we need to make sure // that it contains a definition of the XSL namespace URI if (_root == null) { if ((_prefixMapping == null) || (_prefixMapping.containsValue(Constants.XSLT_URI) == false)) _rootNamespaceDef = false; else _rootNamespaceDef = true; _root = element; } else { SyntaxTreeNode parent = (SyntaxTreeNode)_parentStack.peek(); parent.addElement(element); element.setParent(parent); } element.setAttributes(new AttributeList(attributes)); element.setPrefixMapping(_prefixMapping); if (element instanceof Stylesheet) { // Extension elements and excluded elements have to be // handled at this point in order to correctly generate // Fallback elements from <xsl:fallback>s. getSymbolTable().setCurrentNode(element); ((Stylesheet)element).excludeExtensionPrefixes(this); } _prefixMapping = null; _parentStack.push(element); } /** * SAX2: Receive notification of the end of an element. */ public void endElement(String uri, String localname, String qname) { _parentStack.pop(); } /** * SAX2: Receive notification of character data. */ public void characters(char[] ch, int start, int length) { String string = new String(ch, start, length); SyntaxTreeNode parent = (SyntaxTreeNode)_parentStack.peek(); if (string.length() == 0) return; // If this text occurs within an <xsl:text> element we append it // as-is to the existing text element if (parent instanceof Text) { ((Text)parent).setText(string); return; } // Ignore text nodes that occur directly under <xsl:stylesheet> if (parent instanceof Stylesheet) return; SyntaxTreeNode bro = parent.lastChild(); if ((bro != null) && (bro instanceof Text)) { Text text = (Text)bro; if (!text.isTextElement()) { if ((length > 1) || ( ((int)ch[0]) < 0x100)) { text.setText(string); return; } } } // Add it as a regular text node otherwise parent.addElement(new Text(string)); } private String getTokenValue(String token) { final int start = token.indexOf('"'); final int stop = token.lastIndexOf('"'); return token.substring(start+1, stop); } /** * SAX2: Receive notification of a processing instruction. * These require special handling for stylesheet PIs. */ public void processingInstruction(String name, String value) { // We only handle the <?xml-stylesheet ...?> PI if ((_target == null) && (name.equals("xml-stylesheet"))) { String href = null; // URI of stylesheet found String media = null; // Media of stylesheet found String title = null; // Title of stylesheet found String charset = null; // Charset of stylesheet found // Get the attributes from the processing instruction StringTokenizer tokens = new StringTokenizer(value); while (tokens.hasMoreElements()) { String token = (String)tokens.nextElement(); if (token.startsWith("href")) href = getTokenValue(token); else if (token.startsWith("media")) media = getTokenValue(token); else if (token.startsWith("title")) title = getTokenValue(token); else if (token.startsWith("charset")) charset = getTokenValue(token); } // Set the target to this PI's href if the parameters are // null or match the corresponding attributes of this PI. if ( ((_PImedia == null) || (_PImedia.equals(media))) && ((_PItitle == null) || (_PImedia.equals(title))) && ((_PIcharset == null) || (_PImedia.equals(charset))) ) { _target = href; } } } /** * IGNORED - all ignorable whitespace is ignored */ public void ignorableWhitespace(char[] ch, int start, int length) { } /** * IGNORED - we do not have to do anything with skipped entities */ public void skippedEntity(String name) { } /** * Store the document locator to later retrieve line numbers of all * elements from the stylesheet */ public void setDocumentLocator(Locator locator) { _locator = locator; } /** * Get the line number, or zero * if there is no _locator. */ private int getLineNumber() { int line = 0; if (_locator != null) line = _locator.getLineNumber(); return line; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -