tmiller 2002/06/18 05:57:51
Modified: java/src/org/apache/xalan/xsltc/compiler Parser.java
Log:
added ability to detect/flag superfluous attributes
Revision Changes Path
1.46 +120 -5 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java
Index: Parser.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- Parser.java 17 Jun 2002 18:37:11 -0000 1.45
+++ Parser.java 18 Jun 2002 12:57:51 -0000 1.46
@@ -100,6 +100,7 @@
private Vector _warnings; // Contains all compilation errors
private Hashtable _instructionClasses; // Maps instructions to classes
+ private Hashtable _instructionAttrs;; // reqd and opt attrs
private Hashtable _qNames;
private Hashtable _namespaces;
private QName _useAttributeSets;
@@ -127,6 +128,7 @@
_qNames = new Hashtable(512);
_namespaces = new Hashtable();
_instructionClasses = new Hashtable();
+ _instructionAttrs = new Hashtable();
_variableScope = new Hashtable();
_template = null;
_errors = new Vector();
@@ -137,6 +139,7 @@
_currentImportPrecedence = 1;
initStdClasses();
+ initInstructionAttrs();
initExtClasses();
initSymbolTable();
@@ -591,6 +594,70 @@
return(external);
}
+ private void initAttrTable(String elementName, String[] attrs) {
+ _instructionAttrs.put(getQName(XSLT_URI, XSL, elementName),
+ attrs);
+ }
+
+ private void initInstructionAttrs() {
+ initAttrTable("template",
+ new String[] {"match", "name", "priority", "mode"});
+ initAttrTable("stylesheet",
+ new String[] {"id", "version", "extension-element-prefixes",
+ "exclude-result-prefixes"});
+ initAttrTable("transform",
+ new String[] {"id", "version", "extension-element-prefixes",
+ "exclude-result-prefixes"});
+ initAttrTable("text", new String[] {"disable-output-escaping"});
+ initAttrTable("if", new String[] {"test"});
+ initAttrTable("choose", new String[] {});
+ initAttrTable("when", new String[] {"test"});
+ initAttrTable("otherwise", new String[] {});
+ initAttrTable("for-each", new String[] {"select"});
+ initAttrTable("message", new String[] {"terminate"});
+ initAttrTable("number",
+ new String[] {"level", "count", "from", "value", "format", "lang",
+ "letter-value", "grouping-separator", "grouping-size"});
+ initAttrTable("comment", new String[] {});
+ initAttrTable("copy", new String[] {"use-attribute-sets"});
+ initAttrTable("copy-of", new String[] {"select"});
+ initAttrTable("param", new String[] {"name", "select"});
+ initAttrTable("with-param", new String[] {"name", "select"});
+ initAttrTable("variable", new String[] {"name", "select"});
+ initAttrTable("output",
+ new String[] {"method", "version", "encoding",
+ "omit-xml-declaration", "standalone", "doctype-public",
+ "doctype-system", "cdata-section-elements", "indent",
+ "media-type"});
+ initAttrTable("sort",
+ new String[] {"select", "order", "case-order", "lang", "data-type"});
+ initAttrTable("key", new String[] {"name", "match", "use"});
+ initAttrTable("fallback", new String[] {});
+ initAttrTable("attribute", new String[] {"name", "namespace"});
+ initAttrTable("attribute-set",
+ new String[] {"name", "use-attribute-sets"});
+ initAttrTable("value-of",
+ new String[] {"select", "disable-output-escaping"});
+ initAttrTable("element",
+ new String[] {"name", "namespace", "use-attribute-sets"});
+ initAttrTable("call-template", new String[] {"name"});
+ initAttrTable("apply-templates", new String[] {"select", "mode"});
+ initAttrTable("apply-imports", new String[] {});
+ initAttrTable("decimal-format",
+ new String[] {"name", "decimal-separator", "grouping-separator",
+ "infinity", "minus-sign", "NaN", "percent", "per-mille",
+ "zero-digit", "digit", "pattern-separator"});
+ initAttrTable("import", new String[] {"href"});
+ initAttrTable("include", new String[] {"href"});
+ initAttrTable("strip-space", new String[] {"elements"});
+ initAttrTable("preserve-space", new String[] {"elements"});
+ initAttrTable("processing-instruction", new String[] {"name"});
+ initAttrTable("namespace-alias",
+ new String[] {"stylesheet-prefix", "result-prefix"});
+ }
+
+
+
/**
* Initialize the _instructionClasses Hashtable, which maps XSL element
* names to Java classes in this package.
@@ -842,10 +909,16 @@
* until we have received all child elements of an unsupported element to
* see if any <xsl:fallback> elements exist.
*/
- public SyntaxTreeNode makeInstance(String uri, String prefix, String local){
+
+ private boolean versionIsOne = true;
+
+ public SyntaxTreeNode makeInstance(String uri, String prefix,
+ String local, Attributes attributes)
+ {
+ //boolean isStylesheet = false;
+ SyntaxTreeNode node = null;
QName qname = getQName(uri, prefix, local);
String className = (String)_instructionClasses.get(qname);
- SyntaxTreeNode node = null;
if (className != null) {
try {
@@ -853,11 +926,14 @@
node = (SyntaxTreeNode)clazz.newInstance();
node.setQName(qname);
node.setParser(this);
- if (_locator != null)
+ if (_locator != null) {
node.setLineNumber(_locator.getLineNumber());
+ }
if (node instanceof Stylesheet) {
+ //isStylesheet = true;
_xsltc.setStylesheet((Stylesheet)node);
}
+ checkForSuperfluousAttributes(node, attributes);
}
catch (ClassNotFoundException e) {
ErrorMsg err = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, node);
@@ -912,6 +988,44 @@
}
/**
+ * 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");
+ }
+
+ if (attrQName.startsWith("xml")) 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);
+ reportError(WARNING, err);
+ }
+ }
+ }
+ }
+
+
+ /**
* Parse an XPath expression:
* @parent - XSL element where the expression occured
* @exp - textual representation of the expression
@@ -1121,7 +1235,8 @@
final int col = qname.lastIndexOf(':');
final String prefix = (col == -1) ? null : qname.substring(0, col);
- SyntaxTreeNode element = makeInstance(uri, prefix, localname);
+ SyntaxTreeNode element = makeInstance(uri, prefix,
+ localname, attributes);
if (element == null) {
ErrorMsg err = new ErrorMsg(ErrorMsg.ELEMENT_PARSE_ERR,
prefix+':'+localname);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]