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

📄 xmlparser.java

📁 An open_source WAP browser. include Java code. support WML documents and WBMP images.
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    loop: while (c != delim) {
      switch (c) {
				// Literals never have line ends
      case '\n':
      case '\r':
	c = ' ';
	break;
				// References may be allowed
      case '&':
	if ((flags & LIT_CHAR_REF) > 0) {
	  c = readCh();
	  if (c == '#') {
	    parseCharRef();
	    c = readCh();
	    continue loop;		// check the next character
	  } else if ((flags & LIT_ENTITY_REF) > 0) {
	    unread(c);
	    parseEntityRef(false);
	    c = readCh();
	    continue loop;
	  } else {
	    dataBufferAppend('&');
	  }
	}
	break;

      default:
	break;
      }
      dataBufferAppend(c);
      c = readCh();
    }
    } catch (EOFException e) {
      error("end of input while looking for delimiter (started on line "
	    + startLine + ')', null, new Character(delim).toString());
    }

				// Normalise whitespace if necessary.
    if ((flags & LIT_NORMALIZE) > 0) {
      dataBufferNormalize();
    }

				// Return the value.
    return dataBufferToString();
  }


  /**
    * Try reading external identifiers.
    * <p>The system identifier is not required for notations.
    * @param inNotation Are we in a notation?
    * @return A two-member String array containing the identifiers.
    */
  String[] readExternalIds (boolean inNotation)
    throws java.lang.Exception
  {
    char c;
    String ids[] = new String[2];

    if (tryRead("PUBLIC")) {
      requireWhitespace();
      ids[0] = readLiteral(LIT_NORMALIZE); // public id
      if (inNotation) {
	skipWhitespace();
	if (tryRead('"') || tryRead('\'')) {
	  ids[1] = readLiteral(0);
	}
      } else {
	requireWhitespace();
	ids[1] = readLiteral(0); // system id
      }
    } else if (tryRead("SYSTEM")) {
      requireWhitespace();
      ids[1] = readLiteral(0);	// system id
    }

    return ids;
  }


  /**
    * Test if a character is whitespace.
    * <pre>
    * [1] S ::= (#x20 | #x9 | #xd | #xa)+
    * </pre>
    * @param c The character to test.
    * @return true if the character is whitespace.
    */
  final boolean isWhitespace (char c)
  {
    switch ((int)c) {
    case 0x20:
    case 0x09:
    case 0x0d:
    case 0x0a:
      return true;
    default:
      return false;
    }
  }



  //////////////////////////////////////////////////////////////////////
  // Utility routines.
  //////////////////////////////////////////////////////////////////////


  /**
    * Add a character to the data buffer.
    */
  void dataBufferAppend (char c)
  {
				// Expand buffer if necessary.
    dataBuffer =
      (char[])extendArray(dataBuffer, dataBuffer.length, dataBufferPos);
    dataBuffer[dataBufferPos++] = c;
  }


  /** 
    * Add a string to the data buffer.
    */
  void dataBufferAppend (String s)
  {
    dataBufferAppend(s.toCharArray(), 0, s.length());
  }


  /**
    * Append (part of) a character array to the data buffer.
    */
  void dataBufferAppend (char ch[], int start, int length)
  {
    dataBuffer =
      (char[])extendArray(dataBuffer, dataBuffer.length,
			  dataBufferPos + length);
    System.arraycopy((Object)ch, start,
		     (Object)dataBuffer, dataBufferPos,
		     length);
    dataBufferPos += length;
  }


  /**
    * Normalise whitespace in the data buffer.
    */
  void dataBufferNormalize ()
  {
    int i = 0;
    int j = 0;
    int end = dataBufferPos;

				// Skip whitespace at the start.
    while (j < end && isWhitespace(dataBuffer[j])) {
      j++;
    }

				// Skip whitespace at the end.
    while (end > j && isWhitespace(dataBuffer[end - 1])) {
      end --;
    }

				// Start copying to the left.
    while (j < end) {

      char c = dataBuffer[j++];

				// Normalise all other whitespace to
				// a single space.
      if (isWhitespace(c)) {
	while (j < end && isWhitespace(dataBuffer[j++])) {
	}
	dataBuffer[i++] = ' ';
	dataBuffer[i++] = dataBuffer[j-1];
      } else {
	dataBuffer[i++] = c;
      }
    }

				// The new length is <= the old one.
    dataBufferPos = i;
  }


  /**
    * Convert the data buffer to a string.
    * @param internFlag true if the contents should be interned.
    * @see #intern(char[],int,int)
    */
  String dataBufferToString ()
  {
    String s = new String(dataBuffer, 0, dataBufferPos);
    dataBufferPos = 0;
    return s;
  }


  /**
    * Flush the contents of the data buffer to the handler, if
    * appropriate, and reset the buffer for new input.
    */
  void dataBufferFlush ()
    throws java.lang.Exception
  {
    if (dataBufferPos > 0) {
      switch (currentElementContent) {
      case CONTENT_UNDECLARED:
      case CONTENT_EMPTY:
	// do nothing
	break;
      case CONTENT_MIXED:
      case CONTENT_ANY:
	if (handler != null) {
	  handler.charData(dataBuffer, 0, dataBufferPos);
	}
	break;
      case CONTENT_ELEMENTS:
	if (handler != null) {
	  handler.ignorableWhitespace(dataBuffer, 0, dataBufferPos);
	}
	break;
      }
      dataBufferPos = 0;
    }
  }


  /**
    * Require a string to appear, or throw an exception.
    */
  void require (String delim)
    throws java.lang.Exception
  {
    char ch[] = delim.toCharArray();
    for (int i = 0; i < ch.length; i++) {
      require(ch[i]);
    }
  }


  /**
    * Require a character to appear, or throw an exception.
    */
  void require (char delim)
       throws java.lang.Exception
  {
    char c = readCh();

    if (c != delim) {
      error("expected character", c, new Character(delim).toString());
    }
  }


  /**
    * Return an internalised version of a string.
    * <p>&AElig;lfred uses this method to create an internalised version
    * of all names and attribute values, so that it can test equality
    * with <code>==</code> instead of <code>String.equals()</code>.
    * <p>If you want to be able to test for equality in the same way,
    * you can use this method to internalise your own strings first:
    * <pre>
    * String PARA = handler.intern("PARA");
    * </pre>
    * <p>Note that this will not return the same results as String.intern().
    * @param s The string to internalise.
    * @return An internalised version of the string.
    * @see #intern(char[],int,int)
    * @see java.lang.String#intern
    */
  public String intern (String s)
  {
    char ch[] = s.toCharArray();
    return intern(ch, 0, ch.length);
  }


  /**
    * Create an internalised string from a character array.
    * <p>This is much more efficient than constructing a non-internalised
    * string first, and then internalising it.
    * <p>Note that this will not return the same results as String.intern().
    * @param ch an array of characters for building the string.
    * @param start the starting position in the array.
    * @param length the number of characters to place in the string.
    * @return an internalised string.
    * @see #intern(String)
    * @see java.lang.String#intern
    */
  public String intern (char ch[], int start, int length)
  {
    int index;
    int hash = 0;

				// Generate a hash code.
    for (int i = start; i < start + length; i++) {
      hash = ((hash << 1) & 0xffffff) + (int)ch[i];
    }

    hash = hash % SYMBOL_TABLE_LENGTH;

				// Get the bucket.
    Object bucket[] = (Object[])symbolTable[hash];
    if (bucket == null) {
      symbolTable[hash] = bucket = new Object[8];
    }

				// Search for a matching tuple, and
				// return the string if we find one.
    for (index = 0; index < bucket.length; index += 2) {
      char chFound[] = (char[])bucket[index];

				// Stop when we hit a null index.
      if (chFound == null) {
	break;
      }

				// If they're the same length,
				// check for a match.
				// If the loop finishes, 'index' will
				// contain the current bucket
				// position.
      if (chFound.length == length) {
	for (int i = 0; i < chFound.length; i++) {
				// Stop if there are no more tuples.
	  if (ch[start+i] != chFound[i]) {
	    break;
	  } else if (i == length-1) {
				// That's it, we have a match!
	    return (String)bucket[index+1];
	  }
	}
      }
    }

				// Not found -- we'll have to add it.

				// Do we have to grow the bucket?
    bucket =
      (Object[])extendArray(bucket, bucket.length, index);

				// OK, add it to the end of the
				// bucket.
    String s = new String(ch, start, length);
    bucket[index] = s.toCharArray();
    bucket[index+1] = s;
    symbolTable[hash] = bucket;
    return s;
  }


  /**
    * Ensure the capacity of an array, allocating a new one if
    * necessary.
    */
  Object extendArray (Object array, int currentSize, int requiredSize)
  {
    if (requiredSize < currentSize) {
      return array;
    } else {
      Object newArray = null;
      int newSize = currentSize * 2;

      if (newSize <= requiredSize) {
	newSize = requiredSize + 1;
      }

      if (array instanceof char[]) {
	newArray = new char[currentSize * 2];
      } else if (array instanceof Object[]) {
	newArray = new Object[currentSize * 2];
      }

      System.arraycopy(array, 0, newArray, 0, currentSize);
      return newArray;
    }
  }



  //////////////////////////////////////////////////////////////////////
  // XML query routines.
  //////////////////////////////////////////////////////////////////////


  //
  // Elements
  //

  /**
    * Get the declared elements for an XML document.
    * <p>The results will be valid only after the DTD (if any) has been
    * parsed.
    * @return An enumeration of all element types declared for this
    *         document (as Strings).
    * @see #getElementContentType
    * @see #getElementContentModel
    */
  public Enumeration declaredElements ()
  {
    return elementInfo.keys();
  }


  /**
    * Look up the content type of an element.
    * @param name The element type name.
    * @return An integer constant representing the content type.
    * @see #getElementContentModel
    * @see #CONTENT_UNDECLARED
    * @see #CONTENT_ANY
    * @see #CONTENT_EMPTY
    * @see #CONTENT_MIXED
    * @see #CONTENT_ELEMENTS
    */
  public int getElementContentType (String name)
  {
    Object element[] = (Object[])elementInfo.get(name);
    if (element == null) {
      return CONTENT_UNDECLARED;
    } else {
      return ((Integer)element[0]).intValue();
    }
  }


  /**
    * Look up the content model of an element.
    * <p>The result will always be null unless the content type is
    * CONTENT_ELEMENTS or CONTENT_MIXED.
    * @param name The element type name.
    * @return The normalised content model, as a string.
    * @see #getElementContentType
    */
  public String getElementContentModel (String name)
  {
    Object element[] = (Object[])elementInfo.get(name);
    if (element == null) {
      return null;
    } else {
      return (String)element[1];
    }
  }


  /**
    * Register an element.
    * Array format:
    *  element type
    *  attribute hash table
    */
  void setElement (String name, int contentType,
		   String contentModel, Hashtable attributes)
    throws java.lang.Exception
  {
    Object element[];

				// Try looking up the element
    element = (Object[])elementInfo.get(name);

				// Make a new one if necessary.
    if (element == null) {
      element = new Object[3];
      element[0] = new Integer(CONTENT_UNDECLARED);
      element[1] = null;
      element[2] = null;
    } else if (contentType != CONTENT_UNDECLARED &&
	       ((Integer)element[0]).intValue() != CONTENT_UNDECLARED) {
      error("multiple declarations for element type", name, null);
      return;
    }

				// Insert the content type, if any.
    if (contentType != CONTENT_UNDECLARED) {
      element[0] = new Integer(contentType);
    }

				// Insert the content model, if any.
    if (contentModel != null) {
      element[1] = contentModel;
    }

				// Insert the attributes, if any.
    if (attributes != null) {
      element[2] =attributes;
    }

				// Save the element info.
    elementInfo.put(name,element);
  }


  /**
    * Look up the attribute hash table for an element.
    * The hash table is the second item in the element array.
    */
  Hashtable getElementAttributes (String name)
  {
    Object element[] = (Object[])elementInfo.get(name);
    if (element == null) {
      return null;
    } else {
      return (Hashtable)element[2];
    }
  }



  //
  // Attributes
  //

  /**
    * Get the declared attrib

⌨️ 快捷键说明

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