dtdparser.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,072 行 · 第 1/2 页

JAVA
1,072
字号
      return parseContentParticle(cp, true);    }  }  /**   * Parses a content-particle, i.e. a grammer particle in the DTD   * regexp.   */  private int parseContentParticle(QContentParticle cp, boolean isTop)    throws IOException, SAXException  {    boolean hasCdata = false;    cp._separator = 0;    cp._repeat = 0;    int ch;    ch = expandPE(read());        for (; ch != -1; ch = expandPE(ch)) {      if (ch == '(') {	QContentParticle child = new QContentParticle();	cp.addChild(child);		ch = parseContentParticle(child, false);      }      else if (XmlChar.isNameStart(ch)) {	ch = _xmlParser.parseName(_text, ch);	cp.addChild(_text.toString());      }      else if (ch == '#') {	ch = _xmlParser.parseName(_text, read());	String name = _text.toString();	if (cp._children.size() != 0)	  throw error(L.l("'#{0}' must occur first", name));	if (! isTop)	  throw error(L.l("'#{0}' may only occur at top level", name));	if (name.equals("PCDATA"))	  cp.addChild("#PCDATA");	else	  throw error(L.l("illegal content particle at '#{0}'", name));	hasCdata = true;      }      else	throw error(L.l("expected content particle at {0}", badChar(ch)));      ch = expandPE(ch);      if (ch == '?' || ch == '*' || ch == '+') {        Object child = cp.getChild(cp.getChildSize() - 1);        if (child instanceof QContentParticle) {          QContentParticle cpChild = (QContentParticle) child;          cpChild._repeat = ch;        }        else {          QContentParticle cpChild = new QContentParticle();          cpChild.addChild(child);          cpChild._repeat = ch;          cp.setChild(cp.getChildSize() - 1, cpChild);        }        ch = expandPE(read());      }      if (ch == ')')	break;      else if (cp._separator == 0) {	if (ch == '|') 	  cp._separator = ch;	else if (hasCdata)	  throw error(L.l("#PCDATA must be separated by '|' at {0}",                          badChar(ch)));	else if (ch == ',')	  cp._separator = ch;	else	  throw error(L.l("expected separator at {0}", badChar(ch)));	ch = read();      } else if (ch != cp._separator)	throw error(L.l("expected '{0}' at {1}",                        "" + (char) cp._separator, badChar(ch)));      else	ch = read();    }    ch = expandPE(read());    if (hasCdata && (ch == '+' || ch == '?'))      throw error(L.l("pcdata clause can not have {0}", badChar(ch)));    else if (ch == '*' || ch == '+' || ch == '?') {      cp._repeat = ch;      return read();    }    else      return ch;  }  private int expandPE(int ch)    throws IOException, SAXException  {    ch = _xmlParser.skipWhitespace(ch);        while (ch == '%') {      parsePEReference();      ch = _xmlParser.skipWhitespace(read());    }    return ch;  }  /**   * Parses a PE reference %foo; and inserts the macro text to the input   * stream.   */  private void parsePEReference()    throws IOException, SAXException  {    int ch = _xmlParser.parseName(_buf, read());    if (ch != ';')      throw error(L.l("'%{0};' expects ';' at {1}.  Parameter entities have a '%name;' syntax.", _buf, badChar(ch)));    addPEReference(_text, _buf.toString());  }  /**   * 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) {      _xmlParser.setMacro(entity._value);    }    else if (entity != null && entity.getSystemId() != null) {      _xmlParser.pushInclude(entity.getPublicId(), entity.getSystemId());    }    else {      value.append("%");      value.append(name);      value.append(";");    }  }  /**   * <!ELEMENT name contentspec>   */  private void parseElementDecl(QDocumentType doctype)    throws IOException, SAXException  {    int ch = _xmlParser.skipWhitespace(read());    ch = _xmlParser.parseName(_text, ch);    String name = _text.toString();    ch = _xmlParser.skipWhitespace(ch);    QElementDef def = _dtd.addElement(name);    def.setLocation(getSystemId(), getFilename(), getLine(), getColumn());    boolean needsStartTag = true;    boolean needsEndTag = true;    ch = parseContentSpec(def, ch);    ch = _xmlParser.skipWhitespace(ch);    if (ch != '>')      throw error(L.l("'<!ELEMENT' must close with '>' at {0}", badChar(ch)));  }  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();  }  /**   * <!ATTLIST name (attr type def)*>   */  private void parseAttlistDecl(QDocumentType doctype)    throws IOException, SAXException  {    int ch = _xmlParser.skipWhitespace(read());    ch = _xmlParser.parseName(_text, ch);    String name = _text.toString();    ch = _xmlParser.skipWhitespace(ch);    QElementDef def = _dtd.addElement(name);    while (XmlChar.isNameStart((ch = expandPE(ch)))) {      ch = _xmlParser.parseName(_text, ch);      String attrName = _text.toString();      String attrType = null;      ArrayList<String> enumeration = null;      ch = expandPE(ch);      if (ch == '(') {	attrType = "#ENUM";	enumeration = new ArrayList<String>();	do {	  ch = expandPE(read());	  ch = parseNameToken(_text, ch);	  enumeration.add(_text.toString());	  ch = expandPE(ch);	} while (ch == '|');	if (ch != ')')	  throw error(L.l("expected '{0}' at {1}.  <!ATTRLIST> enumerations definitions are enclosed in '(' ... ')'.", ")", badChar(ch)));	ch = read();      }      else {	ch = _xmlParser.parseName(_text, ch);	attrType = _text.toString();	if (attrType.equals("NOTATION")) {	  enumeration = new ArrayList<String>();	  ch = expandPE(ch);	  if (ch != '(')            throw error(L.l("expected '{0}' at {1}", "(", badChar(ch)));	  do {	    ch = expandPE(read());	    ch = _xmlParser.parseName(_text, ch);	    enumeration.add(_text.toString());	    ch = expandPE(ch);	  } while (ch == '|');	  if (ch != ')')	    throw error(L.l("expected '{0}' at {1}", ")", badChar(ch)));	  ch = read();	}	else if (_attrTypes.get(attrType) != null) {	}        else	  throw error(L.l("expected attribute type at '{0}'", attrType));      }      ch = _xmlParser.skipWhitespace(ch);      String qualifier = null;      String attrDefault = null;      if (ch == '#') {	ch = _xmlParser.parseName(_text, read());	qualifier = "#" + _text.toString();	if (qualifier.equals("#IMPLIED")) {	}	else if (qualifier.equals("#REQUIRED")) {	}	else if (qualifier.equals("#FIXED")) {	  ch = _xmlParser.skipWhitespace(ch);	  ch = parseValue(_text, ch, false);	  attrDefault = _text.toString();	} else	  throw error(L.l("expected attribute default at '{0}'",                      qualifier));      }      else if (ch != '>') {	ch = parseValue(_text, ch, false);	attrDefault = _text.toString();      }      def.addAttribute(attrName, attrType, enumeration,                        qualifier, attrDefault);      if (attrType != null && attrType.equals("ID"))	doctype.setElementId(name, attrName);      ch = _xmlParser.skipWhitespace(ch);    }    if (ch != '>')      throw error(L.l("expected '{0}' at {1}", ">", badChar(ch)));  }  /**   * <!NOTATION name systemId publicId>   */  private void parseNotationDecl(QDocumentType doctype)    throws IOException, SAXException  {    int ch = _xmlParser.skipWhitespace(read());    ch = _xmlParser.parseName(_text, ch);    String name = _text.toString();    ch = _xmlParser.skipWhitespace(ch);    ch = _xmlParser.parseName(_text, ch);    String key = _text.toString();    ch = _xmlParser.skipWhitespace(ch);    ch = parseValue(_text, ch, false);    String id = _text.toString();    ch = _xmlParser.skipWhitespace(ch);    QNotation notation;    if (key.equals("PUBLIC")) {      String systemId = null;      if (ch == '"' || ch == '\'') {	ch = parseValue(_text, ch, false);	ch = _xmlParser.skipWhitespace(ch);	systemId = _text.toString();      }      notation = new QNotation(name, id, systemId);      notation._owner = doctype._owner;      notation.setLocation(getSystemId(), getFilename(), getLine(), getColumn());    }    else if (key.equals("SYSTEM")) {      notation = new QNotation(name, null, id);      notation._owner = doctype._owner;      notation.setLocation(getSystemId(), getFilename(), getLine(), getColumn());    }    else      throw error(L.l("expected PUBLIC or SYSTEM at '{0}'", key));        doctype.addNotation(notation);    doctype.appendChild(notation);    if (ch != '>')      throw error(L.l("expected '{0}' at {1}", ">", badChar(ch)));  }  /**   * externalID ::= PUBLIC publicId systemId   *            ::= SYSTEM systemId   */  private int parseExternalID(int ch)    throws IOException, SAXException  {    ch = _xmlParser.parseName(_text, ch);    String key = _text.toString();    ch = _xmlParser.skipWhitespace(ch);    _extSystemId = null;    _extPublicId = null;    if (key.equals("PUBLIC")) {      ch = parseValue(_text, ch, false);      _extPublicId = _text.toString();      ch = _xmlParser.skipWhitespace(ch);      if (_extPublicId.indexOf('&') > 0)	throw error(L.l("Illegal character '&' in PUBLIC identifier '{0}'",			_extPublicId));      ch = parseValue(_text, ch, false);      ch = _xmlParser.skipWhitespace(ch);      _extSystemId = _text.toString();    }    else if (key.equals("SYSTEM")) {      ch = parseValue(_text, ch, false);      _extSystemId = _text.toString();    }    else      throw error(L.l("expected PUBLIC or SYSTEM at '{0}'", key));    return ch;  }  /**   * <!ENTITY name systemId publicId>   */  private void parseEntityDecl(QDocumentType doctype)    throws IOException, SAXException  {    int ch = _xmlParser.skipWhitespace(read());    boolean isPe = ch == '%';    if (isPe)      ch = _xmlParser.skipWhitespace(read());    ch = _xmlParser.parseName(_text, ch);    String name = _text.toString();    ch = _xmlParser.skipWhitespace(ch);    QEntity entity;    if (ch == '"' || ch == '\'') {      ch = parseValue(_text, ch, false);            entity = new QEntity(name, _text.toString(), null, null);      entity._owner = doctype._owner;      entity.setLocation(getSystemId(), getFilename(), getLine(), getColumn());    }    else {      ch = parseExternalID(ch);      entity = new QEntity(name, null, _extPublicId, _extSystemId);      entity._owner = doctype._owner;      entity.setLocation(getSystemId(), getFilename(), getLine(), getColumn());      ch = _xmlParser.skipWhitespace(ch);      if (! isPe && XmlChar.isNameStart(ch)) {	ch = _xmlParser.parseName(_text, ch);	String key = _text.toString();	if (key.equals("NDATA")) {	  ch = _xmlParser.skipWhitespace(ch);	  ch = _xmlParser.parseName(_text, ch);	  String ndata = _text.toString();	  entity._ndata = ndata;	} else	  throw error(L.l("expected 'NDATA' at '{0}'", key));      }    }          entity._isPe = isPe;    if (isPe)      doctype.addParameterEntity(entity);    else      doctype.addEntity(entity);    doctype.appendChild(entity);    ch = _xmlParser.skipWhitespace(ch);    if (ch != '>')      throw error(L.l("expected '>' at {0}", badChar(ch)));  }  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();  }  private int read()    throws IOException, SAXException  {    return _xmlParser.read();  }  public void unread(int ch)  {    _xmlParser.unread(ch);  }  private String getSystemId()  {    return _xmlParser.getSystemId();  }  private String getFilename()  {    return _xmlParser.getFilename();  }  private XmlParseException error(String msg)  {    return _xmlParser.error(msg);  }  private int getLine()  {    return _xmlParser.getLine();  }  private int getColumn()  {    return _xmlParser.getColumn();  }  private String badChar(int ch)  {    return _xmlParser.badChar(ch);  }    static {    _attrTypes.put("CDATA", "CDATA");    _attrTypes.put("ID", "ID");    _attrTypes.put("IDREF", "IDREF");    _attrTypes.put("IDREFS", "IDREFS");    _attrTypes.put("ENTITY", "ENTITY");    _attrTypes.put("ENTITIES", "ENTITIES");    _attrTypes.put("NMTOKEN", "NMTOKEN");    _attrTypes.put("NMTOKENS", "NMTOKENS");  }}

⌨️ 快捷键说明

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