xmlparser.java

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

JAVA
207 行
字号
import java.util.*;
import java.io.*;

/**
 * XML parser
 */
public class XMLParser { 
    public XMLParser(String fileName, String encoding) { 
        try { 
            InputStream in = getClass().getResourceAsStream(fileName);
            scanner = new XMLScanner(new SafeInputStreamReader(in, encoding));
        } catch (UnsupportedEncodingException err) {
            throw new XMLException("Unsupported encoding " + encoding);
        } 
    }

    public XMLParser(String fileName) { 
        InputStream in = getClass().getResourceAsStream(fileName);
        scanner = new XMLScanner(new InputStreamReader(in));
    }

    public XMLParser(Reader reader) { 
        scanner = new XMLScanner(reader);
    }

    private final void throwException(String message) { 
        throw new XMLException(scanner.getLine(), scanner.getColumn(), message);
    }

    private final XMLElement readElement(String name)
    {
        XMLElement elem = new XMLElement(name);
        String attribute;
        int tkn;
        while (true) { 
            switch (scanner.scan()) { 
            case XMLScanner.XML_GTS:
                return elem;
            case XMLScanner.XML_GT:    
                while ((tkn = scanner.scan()) == XMLScanner.XML_LT) { 
                    if (scanner.scan() != XMLScanner.XML_IDENT) { 
                        throwException("Element name expected");
                    }
                    String siblingName = scanner.getIdentifier();
                    XMLElement sibling = readElement(siblingName);
                    elem.addSibling(sibling);
                }
                if (tkn == XMLScanner.XML_VALUE) { 
                    elem.setValue(scanner.getValue());
                    tkn = scanner.scan();
                }
                if (tkn != XMLScanner.XML_LTS                    
                    || scanner.scan() != XMLScanner.XML_IDENT
                    || !scanner.getIdentifier().equals(name)
                    || scanner.scan() != XMLScanner.XML_GT)
                {
                    throwException("Element is not closed");
                }
                return elem;
            case XMLScanner.XML_IDENT:
                attribute = scanner.getIdentifier();
                if (scanner.scan() != XMLScanner.XML_EQ || scanner.scan() != XMLScanner.XML_VALUE)
                {
                    throwException("Attribute value expected");
                }
                elem.addAttribute(attribute, scanner.getValue());
                continue;
            default:
                throwException("Unexpected token");
            }
        }
    }

    class XMLEnumeration implements Enumeration { 
        XMLElement curr;
        String     rootElemName;

        XMLEnumeration(String rootElemName) { 
            this.rootElemName = rootElemName;
        }

        public boolean hasMoreElements() { 
            if (curr != null) { 
                return true;
            }
            int tkn;
            if ((tkn = scanner.scan()) == XMLScanner.XML_LT) { 
                if (scanner.scan() != XMLScanner.XML_IDENT) { 
                    throwException("Element name expected");
                }
                String elemName = scanner.getIdentifier();
                curr = readElement(elemName);
                return true;
            } 
            if (tkn != XMLScanner.XML_LTS
                || scanner.scan() != XMLScanner.XML_IDENT
                || !scanner.getIdentifier().equals(rootElemName)
                || scanner.scan() != XMLScanner.XML_GT)
            {
                throwException("Root element is not closed");
            } 
            return false;
        }

        public Object nextElement() { 
            if (!hasMoreElements()) { 
                throw new NoSuchElementException();
            }
            Object e = curr;
            curr = null;
            return e;
        }
    }


    private void parseElement(XMLBuilder builder) throws Exception
    { 
        if (scanner.scan() != XMLScanner.XML_IDENT) {
            throwException("Element name expected");
        }
        String name = scanner.getIdentifier();
        builder = builder.addElement(name);
        while (true) { 
            switch (scanner.scan()) { 
            case XMLScanner.XML_GTS:
                builder.closeElement();
                return;
            case XMLScanner.XML_GT:    
                while (true) { 
                    switch (scanner.scan()) { 
                    case XMLScanner.XML_LT:    
                        parseElement(builder);
                        continue;
                    case XMLScanner.XML_VALUE:
                        builder.setValue(scanner.getValue());
                        continue;
                    case XMLScanner.XML_LTS:
                        if (scanner.scan() != XMLScanner.XML_IDENT
                            || !scanner.getIdentifier().equals(name)
                            || scanner.scan() != XMLScanner.XML_GT)
                        {
                            throwException("Element is not closed");
                        }
                        builder.closeElement();
                        return;
                    default:
                        throwException("Unexpected token");
                    }
                }
            case XMLScanner.XML_IDENT:
            {
                String attribute = scanner.getIdentifier();
                if (scanner.scan() != XMLScanner.XML_EQ 
                    || scanner.scan() != XMLScanner.XML_VALUE)
                {
                    throwException("Attribute value expected");
                }
                builder.addAttribute(attribute, scanner.getValue());
                continue;
            }
            default:
                throwException("Unexpected token");
            }
        }
    }

    public void parse(XMLBuilder builder) {
        if (scanner.scan() != XMLScanner.XML_LT) { 
            throwException("No root element");
        }
        try {
            parseElement(builder);
        } catch (Exception x) { 
            throwException(x.getMessage());
        }
    }     
                
    public Enumeration enumerateRootSiblings(String rootElemName) { 
        if (scanner.scan() != XMLScanner.XML_LT
            || scanner.scan() != XMLScanner.XML_IDENT
            || !scanner.getIdentifier().equals(rootElemName)) 
        { 
            throwException("No root element");
        }
        int tkn;
        while ((tkn = scanner.scan()) != XMLScanner.XML_GT) { 
            if (tkn == XMLScanner.XML_EOF) { 
                throwException("No root element");
            }
        }
        return new XMLEnumeration(rootElemName);
    }        

    public XMLElement getRoot() { 
        if (scanner.scan() != XMLScanner.XML_LT
            || scanner.scan() != XMLScanner.XML_IDENT) 
        {
            throwException("No root element");
        }
        String rootElementName = scanner.getIdentifier();
        return readElement(rootElementName);
    }        

    XMLScanner scanner;
    String     rootElemName;
}

⌨️ 快捷键说明

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