xmlscanner.java

来自「Online Map for Mobile」· Java 代码 · 共 234 行

JAVA
234
字号
import java.io.*;

public class XMLScanner { 
    static final int XML_IDENT  = 0;
    static final int XML_VALUE  = 1; 
    static final int XML_LT     = 2; 
    static final int XML_GT     = 3; 
    static final int XML_LTS    = 4; 
    static final int XML_GTS    = 5;
    static final int XML_EQ     = 6; 
    static final int XML_EOF    = 7;
        
    Reader         reader;
    int            line;
    int            column;
    char[]         buf;
    int            slen;
    String         ident;
    boolean        inTag;
    char[]         inputBuf;
    int            inputBufPos;
    int            inputBufUsed;

    XMLScanner(Reader in) {
        reader = in;
        buf = new char[1024];
        inputBuf = new char[256];
        line = 1;
        column = 0;
    }

    static final char hexDigit(int ch) {        
        int d = ch & 0xF;
        return (char)(d <= 9 ? d + '0' : d - 10 + 'A'); 
    }

    int pos;

    final int get() { 
        if (inputBufPos >= inputBufUsed) { 
            try { 
                while ((inputBufUsed = reader.read(inputBuf, 0, inputBuf.length)) == 0);
                pos += inputBufUsed;
            } catch (IOException x) { 
                throw new XMLException(line, column, x.getMessage());
            }
            inputBufPos = 0;
            if (inputBufUsed < 0) { 
                return -1;
            }
        }
        int ch = inputBuf[inputBufPos++];
        if (ch == '\n') { 
            line += 1;
            column = 0;
        } else if (ch == '\t') { 
            column += (column + 8) & ~7;
        } else { 
            column += 1;
        }
        return ch;
    }
    
    final void unget(int ch) { 
        if (ch >= 0) { 
            inputBufPos -= 1;
            if (ch == '\n') {
                line -= 1;
            } else { 
                column -= 1;
            }
        }
    }
    
    private final boolean isLetterOrDigit(int ch) { 
        return (ch >= '0' && ch <= '9') || ch >= 'A';
    }


    private int decodeChar() { 
        switch (get()) { 
        case 'a':
            if (get() != 'm' || get() != 'p' || get() != ';') { 
                throw new XMLException(line, column, "Bad XML file format");
            }
            return '&';
        case 'l':
            if (get() != 't' || get() != ';') { 
                throw new XMLException(line, column, "Bad XML file format");
            }
            return '<';
        case 'g':
            if (get() != 't' || get() != ';') { 
                throw new XMLException(line, column, "Bad XML file format");
            }
            return '>';
        case 'q':
            if (get() != 'u' || get() != 'o' || get() != 't' || get() != ';') { 
                throw new XMLException(line, column, "Bad XML file format");
            }
            return '"';
        default: 
            throw new XMLException(line, column, "Bad XML file format");
        }
    }

    final int scan() 
    {
        int i = 0, ch;

        while (true) { 
            do {
                if ((ch = get()) < 0) {
                    return XML_EOF;
                }
            } while (ch <= ' ');
            
            switch (ch) { 
              case '<':
                ch = get();
                if (ch == '?') { 
                    while ((ch = get()) != '?') { 
                        if (ch < 0) { 
                            throw new XMLException(line, column, "'?' expected");
                        }
                    }
                    if ((ch = get()) != '>') { 
                        throw new XMLException(line, column, "'>' expected");
                    }
                    continue;
                }
                if (inTag) { 
                    throw new XMLException(line, column, "Unexpected '<'");
                }                    
                inTag = true;
                if (ch != '/') { 
                    unget(ch);
                    return XML_LT;
                }
                return XML_LTS;
              case '>':
                if (!inTag) { 
                    throw new XMLException(line, column, "Unexpected '>'");
                }                    
                inTag = false;
                return XML_GT;
              case '/':
                if (inTag) { 
                    if (get() != '>') { 
                        throw new XMLException(line, column, "'>' expected");
                    }
                    inTag = false;
                    return XML_GTS;
                }
                break;
              case '=':
                if (inTag) { 
                    return XML_EQ;
                }
                break;
              case '"':
                while (true) { 
                    ch = get();
                    if (ch < 0) { 
                        throw new XMLException(line, column, "Unclosed string");
                    } else if (ch == '&') { 
                        ch = decodeChar();
                    } else if (ch == '"') { 
                        slen = i;
                        return XML_VALUE;
                    }
                    if (i == buf.length) { 
                        char[] newBuf = new char[buf.length * 2];
                        System.arraycopy(buf, 0, newBuf, 0, i);
                        buf = newBuf;
                    }
                    buf[i++] = (char)ch;
                }
            }
            if (inTag) { 
                while (isLetterOrDigit(ch) || ch == '-' || ch == ':' || ch == '_' || ch == '.') {
                    if (i == buf.length) { 
                        throw new XMLException(line, column, "Too long identifier");
                    }
                    buf[i++] = (char)ch;
                    ch = get();
                }
                unget(ch);
                if (i == 0) { 
                    throw new XMLException(line, column, "Identifier expected");
                }
                slen = i;
                ident = new String(buf, 0, i);
                return XML_IDENT;
            } else { 
                while (ch != '<') { 
                    switch (ch) { 
                      case '>':                              
                        throw new XMLException(line, column, "Unexpected '>'");
                      case '&':
                        ch = decodeChar();
                    }
                    if (i == buf.length) { 
                        char[] newBuf = new char[buf.length * 2];
                        System.arraycopy(buf, 0, newBuf, 0, i);
                        buf = newBuf;
                    }
                    buf[i++] = (char)ch;
                    ch = get();
                }
                unget(ch);
                slen = i;
                return XML_VALUE;
            }
        }
    }
    
    final String getIdentifier() { 
        return ident;
    }

    final String getValue() { 
        return new String(buf, 0, slen);
    }

    final int    getLine() { 
        return line;
    }

    final int    getColumn() { 
        return column;
    }
}

⌨️ 快捷键说明

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