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 `&lt;', `&amp;', `&gt;', `&apos;' and  `&quot;'. All other entities must be defined in an &lt;!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 + -
显示快捷键?