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 '&lt;', '&amp;', '&gt;', '&apos;' and  '&quot;'. All other entities must be defined in an &lt;!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 "&lt;!--" 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 ::= &lt;![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, "&#34;");	i--;      } else if (ch == '\'') {	text.delete(i, i + 1);	text.insert(i, "&#39;");	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 + -
显示快捷键?