⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlreader.java

📁 j2me 上的微型解析器。节约内存。并附应用。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
      }

      if (c == -1) {
        exception(UNEXPECTED_EOF);
      }

      String attrName = readName();

      if (attrName.length() == 0) {
        exception("attr name expected");
      }

      skip();
      read('=');

      skip();
      int delimiter = read();

      if (delimiter != '\'' && delimiter != '"') {
        if (!relaxed) {
          exception(
                  "<"
                  + name
                  + ">: invalid delimiter: "
                  + (char) delimiter);
        }

        delimiter = ' ';
      }

      int i = (attributeCount++) << 1;

      attributes = ensureCapacity(attributes, i + 4);

      attributes[i++] = attrName;

      int p = txtPos;
      pushText(delimiter);

      attributes[i] = pop(p);

      if (delimiter != ' ') {
        read(); // skip endquote
      }
    }
  }

  /** result: isWhitespace; if the setName parameter is set,
       the name of the entity is stored in "name" */

  public final boolean pushEntity() throws IOException {

    read(); // &

    int pos = txtPos;

    while (!eof && peek0 != ';') {
      push(read());
    }

    String code = pop(pos);

    read();

    if (code.length() > 0 && code.charAt(0) == '#') {
      int c =
              (code.charAt(1) == 'x'
               ? Integer.parseInt(code.substring(2), 16)
               : Integer.parseInt(code.substring(1)));
      push(c);
      return c <= ' ';
    }

    String result = (String) entityMap.get(code);
    boolean whitespace = true;

    if (result == null) {
      result = "&" + code + ";";
    }

    for (int i = 0; i < result.length(); i++) {
      char c = result.charAt(i);
      if (c > ' ') {
        whitespace = false;
      }
      push(c);
    }

    return whitespace;
  }

  /** types:
       '<': parse to any token (for nextToken ())
       '"': parse to quote
       ' ': parse to whitespace or '>'
   */

  private final boolean pushText(int delimiter) throws IOException {

    boolean whitespace = true;
    int next = peek0;

    while (!eof
           && next != delimiter) { // covers eof, '<', '"'

      if (delimiter == ' ') {
        if (next <= ' ' || next == '>') {
          break;
        }
      }

      if (next == '&') {
        if (!pushEntity()) {
          whitespace = false;
        }

      } else {
        if (next > ' ') {
          whitespace = false;
        }

        push(read());
      }

      next = peek0;
    }

    return whitespace;
  }

  //--------------- public part starts here... ---------------


  public XmlReader(Reader reader) throws IOException {
    this.reader = reader;

    //peek0 = reader.read();
    //peek1 = reader.read();

    eof = peek0 == -1;

    entityMap = new Hashtable();
    entityMap.put("amp", "&");
    entityMap.put("apos", "'");
    entityMap.put("gt", ">");
    entityMap.put("lt", "<");
    entityMap.put("quot", "\"");

    line = 1;
    column = 1;
  }

  public void defineCharacterEntity(
          String entity,
          String value) {
    entityMap.put(entity, value);
  }

  public int getDepth() {
    return depth;
  }

  public String getPositionDescription() {

    StringBuffer buf =
            new StringBuffer(
                    type < TYPES.length ? TYPES[type] : "Other");

    buf.append(" @" + line + ":" + column + ": ");

    if (type == START_TAG || type == END_TAG) {
      buf.append('<');
      if (type == END_TAG) {
        buf.append('/');
      }

      buf.append(name);
      buf.append('>');
    } else if (isWhitespace) {
      buf.append("[whitespace]");
    } else {
      buf.append(getText());
    }

    return buf.toString();
  }

  public int getLineNumber() {
    return line;
  }

  public int getColumnNumber() {
    return column;
  }

  public boolean isWhitespace() {
    return isWhitespace;
  }

  public String getText() {

    if (text == null) {
      text = pop(0);
    }

    return text;
  }

  public String getName() {
    return name;
  }

  public boolean isEmptyElementTag() {
    return degenerated;
  }

  public int getAttributeCount() {
    return attributeCount;
  }

  public String getAttributeName(int index) {
    if (index >= attributeCount) {
      throw new IndexOutOfBoundsException();
    }
    return attributes[index << 1];
  }

  public String getAttributeValue(int index) {
    if (index >= attributeCount) {
      throw new IndexOutOfBoundsException();
    }
    return attributes[(index << 1) + 1];
  }

  public String getAttributeValue(String name) {

    for (int i = (attributeCount << 1) - 2;
                 i >= 0;
                 i -= 2) {
      if (attributes[i].equals(name)) {
        return attributes[i + 1];
      }
    }

    return null;
  }

  public int getType() {
    return type;
  }

  public int next() throws IOException {

    if (degenerated) {
      type = END_TAG;
      degenerated = false;
      depth--;
      return type;
    }

    txtPos = 0;
    isWhitespace = true;

    do {
      attributeCount = 0;

      name = null;
      text = null;
      type = peekType();

      switch (type) {

      case ENTITY_REF:
        isWhitespace &= pushEntity();
        type = TEXT;
        break;

      case START_TAG:
        parseStartTag();
        break;

      case END_TAG:
        parseEndTag();
        break;

      case END_DOCUMENT:
        break;

      case TEXT:
        isWhitespace &= pushText('<');
        break;

      case CDSECT:
        parseLegacy(true);
        isWhitespace = false;
        type = TEXT;
        break;

      default:
        parseLegacy(false);
      }
    } while (type > TEXT
             || type == TEXT
             && peekType() >= TEXT);

    isWhitespace &= type == TEXT;

    return type;
  }

  //-----------------------------------------------------------------------------
  // utility methods to mak XML parsing easier ...

  /**
   * test if the current event is of the given type and if the
   * name do match. null will match any namespace
   * and any name. If the current event is TEXT with isWhitespace()=
   * true, and the required type is not TEXT, next () is called prior
   * to the test. If the test is not passed, an exception is
   * thrown. The exception text indicates the parser position,
   * the expected event and the current event (not meeting the
   * requirement.
   *
   * <p>essentially it does this
   * <pre>
   *  if (getType() == TEXT && type != TEXT && isWhitespace ())
   *    next ();
   *
   *  if (type != getType
   *  || (name != null && !name.equals (getName ())
   *     throw new XmlPullParserException ( "....");
   * </pre>
   */
  public void require(int type, String name) throws IOException {

    if (this.type == TEXT && type != TEXT && isWhitespace()) {
      next();
    }

    if (type != this.type
        || (name != null && !name.equals(getName()))) {
      exception("expected: " + TYPES[type] + "/" + name);
    }
  }

  /**
   * If the current event is text, the value of getText is
   * returned and next() is called. Otherwise, an empty
   * String ("") is returned. Useful for reading element
   * content without needing to performing an additional
   * check if the element is empty.
   *
   * <p>essentially it does this
   * <pre>
   *   if (getType != TEXT) return ""
   *    String result = getText ();
   *    next ();
   *    return result;
   *  </pre>
   */

  public String readText() throws IOException {

    if (type != TEXT) {
      return "";
    }

    String result = getText();
    next();
    return result;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -