📄 xmlparser.java
字号:
package org.kxml.parser;import java.io.*;import java.util.*;import org.kxml.*;import org.kxml.io.*;/** A simple, pull based "Common XML" parser. Attention: This class has been renamed from DefaultParser for consitency with the org.kxml.io package. */public class XmlParser extends AbstractXmlParser { LookAheadReader reader; boolean relaxed; Vector qNames = new Vector (); boolean immediateClose = false; StartTag current; /** creates a new Parser based on the give reader */ class DefaultParserException extends ParseException { DefaultParserException (String msg, Exception chained) { super (msg, chained, XmlParser.this.reader.getLineNumber (), XmlParser.this.reader.getColumnNumber ()); } } public XmlParser (Reader reader) throws IOException { this.reader = new LookAheadReader (reader); } public String resolveCharacterEntity (String name) throws IOException { throw new DefaultParserException ("Unknown character entity: &"+name+";", null); } /* precondition: <!- consumed */ LegacyEvent parseComment () throws IOException { StringBuffer buf = new StringBuffer (); if (reader.read () != '-') throw new DefaultParserException ("'-' expected", null); int cnt; int lst; while (true) { buf.append (reader.readTo ('-')); if (reader.read () == -1) throw new DefaultParserException ("Unexpected end of file while reading comment", null); cnt = 0; do { lst = reader.read (); cnt++; // adds one more, but first is not cnted } while (lst == '-'); if (lst == '>' && cnt >= 2) break; while (cnt-- > 0) buf.append ('-'); buf.append ((char) lst); } while (cnt-- > 2) buf.append ('-'); return new LegacyEvent (Xml.COMMENT, buf.toString ()); } /* precondition: <! consumed */ LegacyEvent parseDoctype () throws IOException { StringBuffer buf = new StringBuffer (); int nesting = 1; while (true) { int i = reader.read (); switch (i) { case -1: throw new DefaultParserException ("unexpected eof", null); case '<': nesting++; break; case '>': if ((--nesting) == 0) return new LegacyEvent (Xml.DOCTYPE, buf.toString ()); break; } buf.append ((char) i); } } TextEvent parseCData () throws IOException { if (!reader.readTo ('[').equals ("CDATA")) throw new DefaultParserException ("Invalid CDATA start!", null); reader.read (); // skip '[' StringBuffer buf = new StringBuffer (); int c0 = reader.read (); int c1 = reader.read (); while (true) { int c2 = reader.read (); if (c2 == -1) throw new DefaultParserException ("unexpected eof", null); if (c0 == ']' && c1 == ']' && c2 == '>') break; buf.append (c0); c0 = c1; c1 = c2; } return new TextEvent (Xml.TEXT, buf.toString ()); } /* precondition: </ consumed */ ParseEvent parseEndTag () throws IOException { String name = reader.readTo ('>').trim (); if (reader.read () != '>') throw new DefaultParserException ("EndTag </"+name +"> not terminated by '>'", null); int last = qNames.size (); while (true) { if (last == 0) { if (relaxed) return new EndDocument (); throw new DefaultParserException ("tagstack empty parsing </"+name+">", null); } String qName = (String) qNames.elementAt (--last); qNames.removeElementAt (last); if (qName.equals (name)) break; if (!relaxed) throw new DefaultParserException ("StartTag <"+qName +"> does not match end tag </" + name + ">", null); if (qName.toLowerCase ().equals (name.toLowerCase ())) break; current = current.parent; } EndTag result = new EndTag (current); current = current.parent; return result; } /** precondition: <? consumed */ ParseEvent parsePI () throws IOException { StringBuffer buf = new StringBuffer (reader.readTo ('?')); reader.read (); // ? while (reader.peek () != '>') { buf.append ('?'); int r = reader.read (); if (r == -1) throw new DefaultParserException ("Unexpected eof while reading PI", null); buf.append ((char) r); buf.append (reader.readTo ('?')); reader.read (); } reader.read (); // consume > return new LegacyEvent (Xml.PROCESSING_INSTRUCTION, buf.toString ()); } StartTag parseStartTag () throws IOException { current = new StartTag (current, reader, relaxed); String qName = current.name; if (processNamespaces) { try { current.fixNamespaces (); } catch (Exception e) { throw new DefaultParserException (null, e); } } //System.out.println ("tag: ("+next+")"); immediateClose = current.degenerated; if (!immediateClose) qNames.addElement (qName); return current; } TextEvent parseText () throws IOException { StringBuffer buf = new StringBuffer (); int nextChar; int type = Xml.WHITESPACE; do { nextChar = reader.read (); if (nextChar == '&') { String code = reader.readTo (';'); reader.read (); if (code.charAt (0) == '#') buf.append (code.charAt (1) == 'x' ? (char) Integer.parseInt (code.substring (2), 16) : (char) Integer.parseInt (code.substring (1))); else if (code.equals ("lt")) buf.append ('<'); else if (code.equals ("gt")) buf.append ('>'); else if (code.equals ("apos")) buf.append ('\''); else if (code.equals ("quot")) buf.append ('"'); else if (code.equals ("amp")) buf.append ('&'); else buf.append (resolveCharacterEntity (code)); } else { if (nextChar > ' ') type = Xml.TEXT; buf.append ((char) nextChar); } nextChar = reader.peek (); } while (nextChar != '<' && nextChar != -1); return new TextEvent (type, buf.toString ()); } /** precondition: < consumed */ ParseEvent parseSpecial () throws IOException { switch (reader.peek ()) { case -1: throw new DefaultParserException ("Unexpected end of file after reading <", null); case '!': reader.read (); switch (reader.peek ()) { case '-': reader.read (); return parseComment (); case '[': reader.read (); return parseCData (); default: return parseDoctype (); } case '?': reader.read (); return parsePI (); case '/': reader.read (); return parseEndTag (); default: return parseStartTag (); } } protected ParseEvent readImpl () throws IOException { if (immediateClose) { ParseEvent result = new EndTag (current); current = current.getParent (); immediateClose = false; return result; } switch (reader.peek ()) { case '<': reader.read (); return parseSpecial (); case -1: if (current != null && !relaxed) throw new DefaultParserException ("End tag missing for: "+current, null); return new EndDocument (); default: return parseText (); } } /** default is false. Setting relaxed true allows CHTML parsing */ public void setRelaxed (boolean relaxed) { this.relaxed = relaxed; } public int getLineNumber () { return reader.getLineNumber (); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -