xmlparser.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,909 行 · 第 1/3 页
JAVA
1,909 行
_attrValues.add(value); } } int len = _attrNames.size(); for (int i = 0; i < len; i++) { SaxIntern.Entry attrEntry = _attrNames.get(i); String value = _attrValues.get(i); QName name = attrEntry.getQName(); _attributes.add(name, value); } return ch; } /** * Parses an entity reference: * * <pre> * er ::= &#d+; * ::= &name; * </pre> */ private int parseEntityReference() throws IOException, SAXException { int ch; ch = read(); // character reference if (ch == '#') { addText((char) parseCharacterReference()); return read(); } // entity reference else if (XmlChar.isNameStart(ch)) { ch = _reader.parseName(_buf, ch); if (ch != ';' && _strictXml) throw error(L.l("'&{0};' expected ';' at {0}. Entity references have a '&name;' syntax.", _buf, badChar(ch))); else if (ch != ';') { addText('&'); addText(_buf.toString()); return ch; } addEntityReference(_buf.toString()); ch = 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 = read(); int radix = 10; if (ch == 'x') { radix = 16; ch = read(); } int value = 0; for (; ch != ';'; ch = 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; // 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())) { 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 (entity != null) { if (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) { ((DOMBuilder) _contentHandler).entityReference(name); } else addText("&" + name + ";"); } else if (expand && entity._value != null) setMacro(entity._value); else addText("&" + name + ";"); } else { if (_contentHandler instanceof DOMBuilder) { ((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.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; parseXMLDeclaration(oldReader); return true; } 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 int parsePI() throws IOException, SAXException { int ch; ch = 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")) return parsePITail(piName, ch); else { throw error(L.l("<?xml ... ?> occurs after content. The <?xml ... ?> prolog must be at the document start.")); } } private int parsePITail(String piName, int ch) throws IOException, SAXException { ch = skipWhitespace(ch); _text.clear(); while (ch != -1) { if (ch == '?') { if ((ch = read()) == '>') break; else _text.append('?'); } else { _text.append((char) ch); ch = read(); } } _contentHandler.processingInstruction(piName, _text.toString()); return read(); } /** * Parses a comment. The "<!--" has already been read. */ private void parseComment() throws IOException, SAXException { int ch = read(); if (ch != '-') throw error(L.l("expected comment at {0}", badChar(ch))); ch = read(); if (! _skipComments) _buf.clear(); comment: while (ch != -1) { if (ch == '-') { ch = read(); while (ch == '-') { if ((ch = read()) == '>') break comment; else if (_strictComments) throw error(L.l("XML forbids '--' in comments")); else if (ch == '-') { if (! _skipComments) _buf.append('-'); } else { if (! _skipComments) _buf.append("--"); break; } } _buf.append('-'); } else if (! XmlChar.isChar(ch)) { throw error(L.l("bad character {0}", hex(ch))); } else { _buf.append((char) ch); ch = read(); } } if (_skipComments) { } else if (_contentHandler instanceof XMLWriter && ! _skipComments) { ((XMLWriter) _contentHandler).comment(_buf.toString()); _isIgnorableWhitespace = true; } else if (_lexicalHandler != null) { _lexicalHandler.comment(_buf.getBuffer(), 0, _buf.getLength()); _isIgnorableWhitespace = true; } } /** * Parses the contents of a cdata section. * * <pre> * cdata ::= <![CDATA[ ... ]]> * </pre> */ private void parseCdata() throws IOException, SAXException { int ch; if ((ch = read()) != 'C' || (ch = read()) != 'D' || (ch = read()) != 'A' || (ch = read()) != 'T' || (ch = read()) != 'A' || (ch = read()) != '[') { throw error(L.l("expected '<![CDATA[' at {0}", badChar(ch))); } ch = read(); if (_lexicalHandler != null) { _lexicalHandler.startCDATA(); } cdata: while (ch != -1) { if (ch == ']') { ch = read(); while (ch == ']') { if ((ch = read()) == '>') break cdata; else if (ch == ']') addText(']'); else { addText(']'); break; } } addText(']'); } else if (_strictCharacters && ! isChar(ch)) { throw error(L.l("expected character in cdata at {0}", badChar(ch))); } else { addText((char) ch); ch = read(); } } if (_lexicalHandler != null) { _lexicalHandler.endCDATA(); } } /** * Expands the macro value of a PE reference. */ private void addPEReference(CharBuffer value, String name) throws IOException, SAXException { QEntity entity = _dtd.getParameterEntity(name); if (entity == null && ! _dtd.isExternal()) throw error(L.l("'%{0};' is an unknown parameter entity. Parameter entities must be defined in an <!ENTITY> declaration before use.", name)); else if (entity != null && entity._value != null) { setMacro(entity._value); } else if (entity != null && entity.getSystemId() != null) { pushInclude(entity.getPublicId(), entity.getSystemId()); } else { value.append("%"); value.append(name); value.append(";"); } } private static String toAttrDefault(CharBuffer text) { for (int i = 0; i < text.length(); i++) { int ch = text.charAt(i); if (ch == '"') { text.delete(i, i + 1); text.insert(i, """); i--; } else if (ch == '\'') { text.delete(i, i + 1); text.insert(i, "'"); i--; } } return text.toString(); } /** * externalID ::= PUBLIC publicId systemId * ::= SYSTEM systemId */ private int parseExternalID(int ch) throws IOException, SAXException { ch = _reader.parseName(_text, ch); String key = _text.toString(); ch = skipWhitespace(ch); _extSystemId = null; _extPublicId = null; if (key.equals("PUBLIC")) { _extPublicId = parseValue(ch); ch = skipWhitespace(read()); if (_extPublicId.indexOf('&') > 0) throw error(L.l("Illegal character '&' in PUBLIC identifier '{0}'", _extPublicId)); _extSystemId = parseValue(ch); ch = skipWhitespace(read()); } else if (key.equals("SYSTEM")) { _extSystemId = parseValue(ch); ch = read(); } else throw error(L.l("expected PUBLIC or SYSTEM at '{0}'", key)); return ch; } /** * 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 String parseValue(int ch) throws IOException, SAXException { int end = ch; char []valueBuffer = _valueBuffer; int valueLength = 0; if (end != '\'' && end != '"') { valueBuffer[valueLength++] = (char) end; for (ch = read(); ch >= 0 && XmlChar.isNameChar(ch); ch = read()) { valueBuffer[valueLength++] = (char) ch; } String value = new String(valueBuffer, 0, valueLength); throw error(L.l("XML attribute value must be quoted at '{0}'. XML attribute syntax is either attr=\"value\" or attr='value'.", value)); } ch = read(); while (ch >= 0 && ch != end) { if (ch == '&') { if ((ch = read()) == '#') { valueBuffer[valueLength++] = (char) parseCharacterReference(); } else if (XmlChar.isNameStart(ch)) { ch = _reader.parseName(_buf, ch); String name = _buf.toString(); if (ch != ';') throw error(L.l("expected '{0}' at {1}", ";", badChar(ch))); else { int lookup = _entities.getEntity(name); if (lookup >= 0 && lookup <= 0xffff) { ch = read(); valueBuffer[valueLength++] = (char) lookup; continue; } QEntity entity = _dtd == null ? null : _dtd.getEntity(name); if (entity != null && entity._value != null) setMacroAttr(entity._value); else throw error(L.l("expected local reference at '&{0};'", name)); } } } else { if (ch == '\r') { ch = read(); if (ch != '\n') { valueBuffer[valueLength++] = '\n'; continue; } } valueBuffer[valueLength++] = (char) ch; } ch = read(); } return new String(valueBuffer, 0, valueLength); } private boolean isWhitespace(int ch) { return ch <= 0x20 && (ch == 0x20 || ch == 0x9 || ch == 0xa || ch == 0xd); } private boolean isChar(int ch) { return (ch >= 0x20 && ch <= 0xd7ff || ch == 0x9 || ch == 0xa || ch == 0xd || ch >= 0xe000 && ch <= 0xfffd); } /** * Returns the hex representation of a byte. */ private static String hex(int value) { CharBuffer cb = CharBuffer.allocate(); for (int b = 3; b >= 0; b--) { int v = (value >> (4 * b)) & 0xf; if (v < 10) cb.append((char) (v + '0')); else cb.append((char) (v - 10 + 'a')); } return cb.close(); } /** * Returns the current filename. */ public String getFilename() { return _filename; } /** * Returns the current line. */ public int getLine() { return _line; } /** * Returns the current column. */ int getColumn() { return -1; } /** * Returns the opening line of the current node. */ int getNodeLine() { if (_elementTop > 0) return _elementLines[_elementTop - 1]; else return 1; } /** * Returns the current public id being read. */ public String getPublicId() { if (_reader != null) return _reader.getPublicId(); else return _publicId; } /** * Returns the current system id being read. */ public String getSystemId() { if (_reader != null) return _reader.getSystemId(); else if (_systemId != null) return _systemId; else return _filename; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?