📄 xmlparser.java
字号:
if (last == 0)
throw new DefaultParserException
("tagstack empty parsing </"+closePending+">", null);
String qName = (String) qNames.elementAt (--last);
qNames.removeElementAt (last);
if (qName.equals (closePending)
|| (relaxed && qName.toLowerCase ().equals
(closePending.toLowerCase ())))
closePending = null;
else if (!relaxed)
throw new DefaultParserException
("StartTag <"+qName
+"> does not match end tag </" + closePending + ">", null);
Tag result = new Tag
(Xml.END_TAG, current, current.namespace, current.name);
current = current.parent;
return result;
}
/** precondition: <? consumed */
ParseEvent parsePI () throws IOException {
StringBuffer buf = new StringBuffer ();
readTo ('?', buf);
readChar (); // ?
while (peekChar () != '>') {
buf.append ('?');
int r = readChar ();
if (r == -1) throw new DefaultParserException
(UNEXPECTED_EOF, null);
buf.append ((char) r);
readTo ('?', buf);
readChar ();
}
readChar (); // consume >
return new ParseEvent
(Xml.PROCESSING_INSTRUCTION, buf.toString ());
}
StartTag parseStartTag () throws IOException {
String qname = readName ();
Vector attributes = null;
immediateClose = false;
while (true) {
skipWhitespace ();
int c = peekChar ();
if (c == -1)
throw new DefaultParserException (UNEXPECTED_EOF, null);
if (c == '/') {
immediateClose = true;
readChar ();
skipWhitespace ();
if (readChar () != '>')
throw new DefaultParserException
("illegal element termination", null);
break;
}
if (c == '>') {
readChar ();
break;
}
String attrName = readName ();
if (attrName.length() == 0)
throw new DefaultParserException("illegal char / attr", null);
skipWhitespace ();
if (readChar () != '=') {
throw new DefaultParserException
("Attribute name "+attrName
+"must be followed by '='!", null);
}
skipWhitespace ();
int delimiter = readChar ();
if (delimiter != '\'' && delimiter != '"') {
if (!relaxed)
throw new DefaultParserException
("<" + qname + ">: invalid delimiter: "
+ (char) delimiter, null);
delimiter = ' ';
}
StringBuffer buf = new StringBuffer ();
readText (buf, (char) delimiter);
if (attributes == null) {
attributes = new Vector ();
}
attributes.addElement (new Attribute (null, attrName, buf.toString ()));
if (delimiter != ' ') {
readChar (); // skip endquote
}
}
try {
current = new StartTag
(current, Xml.NO_NAMESPACE, qname, attributes,
immediateClose, processNamespaces);
}
catch (Exception e) {
throw new DefaultParserException (e.toString (), e);
}
if (!immediateClose)
qNames.addElement (qname);
return current;
}
int readText (StringBuffer buf, char delimiter) throws IOException {
int type = Xml.WHITESPACE;
int nextChar;
while (true) {
nextChar = peekChar ();
if (nextChar == -1
|| nextChar == delimiter
|| (delimiter == ' '
&& (nextChar == '>' || nextChar < ' '))) break;
readChar ();
if (nextChar == '&') {
String code = readTo (';', new StringBuffer ()).toString ();
readChar ();
if (code.charAt (0) == '#') {
nextChar = (code.charAt (1) == 'x'
? Integer.parseInt (code.substring (2), 16)
: Integer.parseInt (code.substring (1)));
if (nextChar > ' ')
type = Xml.TEXT;
buf.append ((char) nextChar);
} 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));
type = Xml.TEXT;
}
} else {
if (nextChar > ' ')
type = Xml.TEXT;
buf.append ((char) nextChar);
}
}
return type;
}
/** precondition: < consumed */
ParseEvent parseSpecial () throws IOException {
switch (peekChar ()) {
case -1: throw new DefaultParserException
(UNEXPECTED_EOF, null);
case '!':
readChar ();
switch (peekChar ()) {
case '-':
readChar ();
return parseComment ();
case '[':
readChar ();
return parseCData ();
default:
return parseDoctype ();
}
case '?':
readChar ();
return parsePI ();
case '/':
readChar ();
return parseEndTag ();
default:
return parseStartTag ();
}
}
public ParseEvent read () throws IOException{
if (next == null)
peek ();
ParseEvent result = next;
next = null;
return result;
}
public ParseEvent peek () throws IOException {
if (next == null) {
if (immediateClose) {
next = new Tag
(Xml.END_TAG, current, current.namespace, current.name);
current = current.getParent ();
immediateClose = false;
}
else if (closePending != null) {
next = checkEndTag ();
}
else {
switch (peekChar ()) {
case '<':
readChar ();
next = parseSpecial ();
break;
case -1:
if (current != null && !relaxed)
throw new DefaultParserException
("End tag missing for: "+current, null);
next = new ParseEvent (Xml.END_DOCUMENT, null);
break;
default: {
StringBuffer buf = new StringBuffer ();
int type = readText (buf, '<');
next = new ParseEvent (type, buf.toString ());
}
}
}
}
return next;
}
/** default is false. Setting relaxed true
* allows CHTML parsing */
public void setRelaxed (boolean relaxed) {
this.relaxed = relaxed;
}
public int getLineNumber () {
return line;
}
public int getColumnNumber () {
return column;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -