2003/11/18 08:02:31
authordavid <david@xwt.org>
Fri, 30 Jan 2004 07:41:46 +0000 (07:41 +0000)
committerdavid <david@xwt.org>
Fri, 30 Jan 2004 07:41:46 +0000 (07:41 +0000)
darcs-hash:20040130074146-0c9ea-f5b357ba2f758ee40faaaabd9aa203ad28b290d5.gz

src/org/xwt/util/XML.java

index 41f91ea..099acce 100644 (file)
@@ -159,20 +159,6 @@ public abstract class XML
                     readChars(false, "-->", false); 
                     col += 3; off += 3; len -= 3;
                     break;
-                case '[': 
-                    if (!buffer(7)
-                            || buf[off+1] != 'C' || buf[off+2] != 'D' || buf[off+3] != 'A'
-                            || buf[off+4] != 'T' || buf[off+5] != 'A' || buf[off+6] != '[') {
-                        col++; off--; len++; 
-                        // Conditional    '<![' (Char* - (Char* ']]>' Char*)) ']]>'
-                        readChars(false, "]]>", false); 
-                    } else {
-                        col += 7; off += 7; len -=7;
-                        // CDATA          '<![CDATA[' (Char* - (Char* ']]>' Char*))        ']]>'
-                        readChars(true, "]]>", false);
-                    } 
-                    col += 3; off += 3; len -= 3;
-                    break;
 
                 // we don't care about the following definitions
 
@@ -244,6 +230,19 @@ public abstract class XML
             if (!buffer(2)) throw new EOFException("Unexpected EOF at end of Processing Instruction");
             col += 2; off += 2; len -= 2;
 
+        } else if (s == '[') {
+            if (!buffer(7)
+                    || buf[off+1] != 'C' || buf[off+2] != 'D' || buf[off+3] != 'A'
+                    || buf[off+4] != 'T' || buf[off+5] != 'A' || buf[off+6] != '[') {
+                col++; off--; len++; 
+                // Conditional    '<![' (Char* - (Char* ']]>' Char*)) ']]>'
+                readChars(false, "]]>", false); 
+            } else {
+                col += 7; off += 7; len -=7;
+                // CDATA          '<![CDATA[' (Char* - (Char* ']]>' Char*))        ']]>'
+                readChars(true, "]]>", false);
+            } 
+            col += 3; off += 3; len -= 3;
         } else {
             if (s == '/') {
                 // End Tag        '</' Name S? '>'
@@ -380,9 +379,8 @@ public abstract class XML
     private final void readAttribute() throws IOException, XMLException {
         int ref = 0;
         int prefix = 0;
-        boolean xmlns = false;
-        String n, v;
-        n = v = null;
+        String n, v, p, u; // attribute name, value, prefix and uri respectively
+        n = v = p = u = null;
         char s;
 
         // find the element name (defined in XML Spec: section 2.3)
@@ -395,27 +393,21 @@ public abstract class XML
                 break;
             } else if (s == ':' && ref > 0 && prefix < 1) {
                 // we have a definition of the prefix range available
-                prefix = ref+1; 
+                prefix = ref+1;
             } else if (!NameChar(s)) {
                 throw new MarkupException("attribute name contains invalid characters", getLine(), getCol());
             }
         }
 
-        // work out if attribute is related to XML Namespacing
-        if (ref > 4 && buf[off] == 'x' && buf[off+1] == 'm' && buf[off+2] == 'l' && buf[off+3] == 'n' && buf[off+4] == 's') {
-            if (ref == 5) {
-                xmlns = true;
-            } else if (prefix > 0) {
-                xmlns = true;
-                n = new String(buf, off+prefix, ref-prefix);
-            } else {
-                n = new String(buf, off, ref);
-            }
-        } else {
-            n = new String(buf, off, ref);
+        // determine prefix and key name
+        if (prefix > 0) {
+            p = new String(buf, off, prefix-1);
+            col += prefix; off += prefix; len -= prefix; ref -= prefix;
         }
+        n = new String(buf, off, ref);
         col += ref; off += ref; len -= ref;
 
+        // find name/value divider ('=')
         readWhitespace();
         if (!buffer(1)) throw new EOFException("Unexpected EOF before attribute '=' divider");
         if (buf[off] != '=') throw new MarkupException("attribute name not followed by '=' sign", getLine(), getCol());
@@ -450,15 +442,14 @@ public abstract class XML
         // remove end wrapper character
         col++; off++; len--;
 
-        if (xmlns) {
-            if (n == null) {
-                if (current.defaultUri != null) {
-                    current.addError(new NCException("default namespace definition repeated", getLine(), getCol()));
-                } else {
-                    current.defaultUri = v;
-                }
+        // process attribute
+        if (p != null && p.equals("xmlns")) {
+            current.urimap.put(n, v);
+        } else if (n.equals("xmlns")) {
+            if (current.defaultUri != null) {
+                current.addError(new NCException("default namespace definition repeated", getLine(), getCol()));
             } else {
-                current.urimap.put(n, v);
+                current.defaultUri = v;
             }
         } else {
             // check to see if attribute is a repeat
@@ -466,10 +457,21 @@ public abstract class XML
                 "attribute name '"+n+"' may not appear more than once in the same element tag", getLine(), getCol()
             );
 
+            // find attribute uri
+            if (p == null) {
+                u = current.uri;
+            } else {
+                for (Element e = current; e != null && u == null; e = e.prev) {
+                    u = (String)e.urimap.get(p);
+                }
+                if (u == null) current.addError(new NCException("undefined attribute prefix '"+current.prefix+"'", getLine(), getCol()));
+            }
+
             // add attribute to the attribute arrays
             if (current.len == current.keys.length) current.morekeys();
             current.keys[current.len] = n;
             current.vals[current.len] = v;
+            current.uris[current.len] = u;
             current.len++;
         }
     }
@@ -802,6 +804,9 @@ public abstract class XML
         /** An array of attribute values. */
         public String[] vals;
 
+        /** An array of attribute uris. */
+        public String[] uris;
+
         /** An array of non-fatal errors related to this element. */
         public XMLException[] errors;
 
@@ -828,6 +833,7 @@ public abstract class XML
             urimap = new Hash(3,3);
             keys = new String[10];
             vals = new String[10];
+            uris = new String[10];
             errors = new XMLException[] {};
             len = 0;
         }
@@ -836,14 +842,16 @@ public abstract class XML
         void morekeys() {
             String[] newkeys = new String[keys.length+5];
             String[] newvals = new String[vals.length+5];
+            String[] newuris = new String[uris.length+5];
             System.arraycopy(keys, 0, newkeys, 0, keys.length);
             System.arraycopy(vals, 0, newvals, 0, vals.length);
-            keys = newkeys; vals = newvals;
+            System.arraycopy(uris, 0, newuris, 0, uris.length);
+            keys = newkeys; vals = newvals; uris = newuris;
         }
 
         /** empty out the arrays */
         void clear() {
-            for (int i=0; len > i; i++) { keys[i] = null; vals[i] = null; }; len = 0;
+            for (int i=0; len > i; i++) { keys[i] = null; vals[i] = null; uris[i] = null; }; len = 0;
             errors = new XMLException[] {};
         }