xmlparser.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,651 行 · 第 1/5 页
JAVA
2,651 行
addEntityReference(_buf.toString()); ch = _reader.read(); return ch; } else if (_strictXml) { throw error(L.l("expected name at {0}", badChar(ch))); } else { addText('&'); return ch; } } private int parseCharacterReference() throws IOException, SAXException { int ch = _reader.read(); int radix = 10; if (ch == 'x') { radix = 16; ch = _reader.read(); } int value = 0; for (; ch != ';'; ch = _reader.read()) { if (ch >= '0' && ch <= '9') value = radix * value + ch - '0'; else if (radix == 16 && ch >= 'a' && ch <= 'f') value = radix * value + ch - 'a' + 10; else if (radix == 16 && ch >= 'A' && ch <= 'F') value = radix * value + ch - 'A' + 10; else throw error(L.l("malformed entity ref at {0}", badChar(ch))); } if (value > 0xffff) throw error(L.l("malformed entity ref at {0}", "" + value)); // xml/0072 if (_strictCharacters && ! isChar(value)) throw error(L.l("illegal character ref at {0}", badChar(value))); return value; } /** * Looks up a named entity reference, filling the text. */ private void addEntityReference(String name) throws IOException, SAXException { boolean expand = ! _entitiesAsText || _hasDoctype || ! _switchToXml; // XXX: not quite the right logic. There should be a soft expandEntities if (! expand) { addText("&" + name + ";"); return; } int ch = _entities.getEntity(name); if (ch >= 0 && ch <= 0xffff) { addText((char) ch); return; } QEntity entity = _dtd == null ? null : _dtd.getEntity(name); if (! _expandEntities) { addText("&" + name + ";"); return; } if (entity == null && (_dtd == null || _dtd.getName() == null || ! _dtd.isExternal())) { if (_strictXml) throw error(L.l("`&{0};' is an unknown entity. XML predefines only `<', `&', `>', `'' and `"'. All other entities must be defined in an <!ENTITY> definition in the DTD.", name)); else { if (expand && _contentHandler instanceof DOMBuilder) { appendText(); ((DOMBuilder) _contentHandler).entityReference(name); } else addText("&" + name + ";"); } } else if (entity != null) { if (expand && entity._isSpecial && entity._value != null) addText(entity._value); else if (entity.getSystemId() != null) { if (pushSystemEntity(entity)) { } /* XXX:?? else if (strictXml) { throw error(L.l("can't open external entity at `&{0};'", name)); } */ else if (_contentHandler instanceof DOMBuilder) { appendText(); ((DOMBuilder) _contentHandler).entityReference(name); } else addText("&" + name + ";"); } else if (expand && entity._value != null) setMacro(entity._value); else addText("&" + name + ";"); } else { if (expand && _contentHandler instanceof DOMBuilder) { appendText(); ((DOMBuilder) _contentHandler).entityReference(name); } else // XXX: error? addText("&" + name + ";"); } } private boolean pushSystemEntity(QEntity entity) throws IOException, SAXException { String publicId = entity.getPublicId(); String systemId = entity.getSystemId(); String value = null; InputSource source = null; ReadStream is = null; if (_entityResolver != null) source = _entityResolver.resolveEntity(publicId, systemId); if (source != null && source.getByteStream() != null) is = Vfs.openRead(source.getByteStream()); else if (source != null && source.getCharacterStream() != null) is = Vfs.openRead(source.getCharacterStream()); else if (source != null && source.getSystemId() != null && _searchPath.lookup(source.getSystemId()).isFile()) { _owner.addDepend(_searchPath.lookup(source.getSystemId())); is = _searchPath.lookup(source.getSystemId()).openRead(); } else if (systemId != null && ! systemId.equals("")) { String path = systemId; if (path.startsWith("file:")) path = path.substring(5); if (_searchPath != null && _searchPath.lookup(path).isFile()) { _owner.addDepend(_searchPath.lookup(path)); is = _searchPath.lookup(path).openRead(); } } if (is == null) return false; _filename = systemId; _systemId = systemId; Path oldSearchPath = _searchPath; Path path = is.getPath(); if (path != null) { _owner.addDepend(path); if (_searchPath != null) { _searchPath = path.getParent(); _reader.setSearchPath(oldSearchPath); } } _is = is; _line = 1; XmlReader oldReader = _reader; _reader = null; int ch = parseXMLDeclaration(oldReader); unread(ch); return true; } /** * Parses an attribute value. * * <pre> * value ::= '[^']*' * ::= "[^"]*" * ::= [^ />]* * </pre> * * @param value the CharBuffer which will contain the value. * @param ch the next character from the input stream. * @param isGeneral true if general entities are allowed. * * @return the following character from the input stream */ private int parseValue(CharBuffer value, int ch, boolean isGeneral) throws IOException, SAXException { int end = ch; value.clear(); if (end == '\'' || end == '"') ch = _reader.read(); else if (_strictAttributes) { value.append((char) end); for (ch = _reader.read(); ch >= 0 && XmlChar.isNameChar(ch); ch = _reader.read()) value.append((char) ch); throw error(L.l("XML attribute value must be quoted at `{0}'. XML attribute syntax is either attr=\"value\" or attr='value'.", value)); } else end = 0; while (ch != -1 && (end != 0 && ch != end || end == 0 && isAttributeChar(ch))) { if (end == 0 && ch == '/') { ch = _reader.read(); if (! isWhitespace(ch) && ch != '>') { value.append('/'); value.append((char) ch); } else { unread(ch); return '/'; } } else if (ch == '&' && ! _entitiesAsText) { if ((ch = _reader.read()) == '#') value.append((char) parseCharacterReference()); else if (! isGeneral) { value.append('&'); value.append((char) ch); } else if (XmlChar.isNameStart(ch)) { ch = _reader.parseName(_buf, ch); String name = _buf.toString(); if (ch != ';' && _strictXml) throw error(L.l("expected `{0}' at {1}", ";", badChar(ch))); else if (ch != ';') { value.append('&'); value.append(name); continue; } else { int lookup = _entities.getEntity(name); if (lookup >= 0 && lookup <= 0xffff) { ch = _reader.read(); value.append((char) lookup); continue; } QEntity entity = _dtd == null ? null : _dtd.getEntity(name); if (entity != null && entity._value != null) setMacroAttr(entity._value); else if (_strictXml) throw error(L.l("expected local reference at `&{0};'", name)); else { value.append('&'); value.append(name); value.append(';'); } } } } else if (ch == '%' && ! isGeneral) { ch = _reader.read(); if (! XmlChar.isNameStart(ch)) { value.append('%'); continue; } else { ch = _reader.parseName(_buf, ch); if (ch != ';') throw error(L.l("expected `{0}' at {1}", ";", badChar(ch))); else addPEReference(value, _buf.toString()); } } else if (ch == '<' && _isJsp) { value.append('<'); ch = _reader.read(); if (ch != '%') continue; value.append('%'); ch = _reader.read(); while (ch >= 0) { if (ch == '%') { ch = _reader.read(); if (ch == '>') { value.append("%>"); break; } else value.append('%'); } else { value.append((char) ch); ch = _reader.read(); } } } else if (isGeneral) { if (ch == '\r') { ch = _reader.read(); if (ch != '\n') { value.append('\n'); continue; } } value.append((char) ch); } else if (ch == '\r') { value.append(' '); if ((ch = _reader.read()) != '\n') continue; } else if (ch == '\n') value.append(' '); else value.append((char) ch); ch = _reader.read(); } if (end != 0) ch = _reader.read(); return ch; } private boolean isAttributeChar(int ch) { switch (ch) { case ' ': case '\t': case '\n': case '\r': return false; case '<': case '>': case '\'':case '"': case '=': return false; default: return true; } } private void parsePcdata(QNode node) throws IOException, SAXException { int ch; String tail = "</" + node.getNodeName() + ">"; _text.clear(); ch = _reader.read(); if (ch == '\n') ch = _reader.read(); for (; ch != -1; ch = _reader.read()) { addText((char) ch); if (_text.endsWith(tail)) { _text.setLength(_text.length() - tail.length()); if (_text.length() > 1 && _text.charAt(_text.length() - 1) == '\n') _text.setLength(_text.length() - 1); appendText(); return; } } throw error("bad pcdata"); } private int parseXMLDeclaration(XmlReader oldReader) throws IOException, SAXException { int startOffset = _is.getOffset(); boolean isEBCDIC = false; int ch = _is.read(); XmlReader reader = null; // utf-16 starts with \xfe \xff if (ch == 0xfe) { ch = _is.read(); if (ch == 0xff) { _owner.setAttribute("encoding", "UTF-16"); _is.setEncoding("utf-16"); reader = new Utf16Reader(this, _is); ch = reader.read(); } } // utf-16 rev starts with \xff \xfe else if (ch == 0xff) { ch = _is.read(); if (ch == 0xfe) { _owner.setAttribute("encoding", "UTF-16"); _is.setEncoding("utf-16"); reader = new Utf16Reader(this, _is); ((Utf16Reader) reader).setReverse(true); ch = reader.read(); } } // utf-16 can also start with \x00 < else if (ch == 0x00) { ch = _is.read(); _owner.setAttribute("encoding", "UTF-16"); _is.setEncoding("utf-16"); reader = new Utf16Reader(this, _is); } // utf-8 BOM is \xef \xbb \xbf else if (ch == 0xef) { ch = _is.read(); if (ch == 0xbb) { ch = _is.read(); if (ch == 0xbf) { ch = _is.read(); _owner.setAttribute("encoding", "UTF-8"); _is.setEncoding("utf-8"); reader = new Utf8Reader(this, _is); } } } else if (ch == 0x4c) { // ebcdic // xml/00l1 _is.unread(); // _is.setEncoding("cp037"); _is.setEncoding("cp500"); isEBCDIC = true; reader = new XmlReader(this, _is); ch = reader.read(); } else { int ch2 = _is.read(); if (ch2 == 0x00) { _owner.setAttribute("encoding", "UTF-16LE"); _is.setEncoding("utf-16le"); reader = new Utf16Reader(this, _is); ((Utf16Reader) reader).setReverse(true); } else if (ch2 > 0) _is.unread(); } if (reader != null && reader != oldReader) { } else if (_policy instanceof HtmlPolicy || _is.getSource() instanceof ReaderWriterStream) { reader = new XmlReader(this, _is); } else { reader = new Utf8Reader(this, _is); } if (ch == '\n') reader.setLine(2); reader.setSystemId(_systemId); if (_systemId == null) reader.setSystemId(_filename); reader.setFilename(_filename); reader.setPublicId(_publicId); reader.setNext(oldReader); _reader = reader; /* XXX: this might be too strict. */ /* if (! strictXml) { for (; XmlChar.isWhitespace(ch); ch = reader.read()) { } } */ if (ch != '<') return ch; if (parseXMLDecl(_reader) && isEBCDIC) { // EBCDIC requires a re-read _is.setOffset(startOffset); ch = _reader.read(); if (ch != '<') throw new IllegalStateException(); parseXMLDecl(_reader); } return _reader.read(); } private boolean parseXMLDecl(XmlReader reader) throws IOException, SAXException { int ch = reader.read(); if (ch != '?') { unread((char) ch); unread('<'); return false; } ch = _reader.read(); if (! XmlChar.isNameStart(ch)) throw error(L.l("expected name after '<?' at {0}. Processing instructions expect a name like <?foo ... ?>", badChar(ch))); ch = _reader.parseName(_text, ch); String piName = _text.toString(); if (! piName.equals("xml")) { ch = parsePITail(piName, ch); unread(ch);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?