📄 xmlparser.java
字号:
parseNotationType(); return typeString; } else if ("CDATA" == typeString || "ID" == typeString || "IDREF" == typeString || "IDREFS" == typeString || "ENTITY" == typeString || "ENTITIES" == typeString || "NMTOKEN" == typeString || "NMTOKENS" == typeString) { return typeString; } } else { if ("NOTATION".equals(typeString)) { parseNotationType(); return typeString; } else if ("CDATA".equals(typeString) || "ID".equals(typeString) || "IDREF".equals(typeString) || "IDREFS".equals(typeString) || "ENTITY".equals(typeString) || "ENTITIES".equals(typeString) || "NMTOKEN".equals(typeString) || "NMTOKENS".equals(typeString)) { return typeString; } } error("illegal attribute type", typeString, null); return null; } } /** * Parse an enumeration. * <pre> * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')' * </pre> * <p>NOTE: the '(' has already been read. */ private void parseEnumeration(boolean isNames) throws Exception { dataBufferAppend('('); // Read the first token. skipWhitespace(); dataBufferAppend(readNmtoken(isNames)); // Read the remaining tokens. skipWhitespace(); while (!tryRead(')')) { require('|'); dataBufferAppend('|'); skipWhitespace(); dataBufferAppend(readNmtoken (isNames)); skipWhitespace(); } dataBufferAppend(')'); } /** * Parse a notation type for an attribute. * <pre> * [58] NotationType ::= 'NOTATION' S '(' S? NameNtoks * (S? '|' S? name)* S? ')' * </pre> * <p>NOTE: the 'NOTATION' has already been read */ private void parseNotationType() throws Exception { requireWhitespace(); require('('); parseEnumeration(true); } /** * Parse the default value for an attribute. * <pre> * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' * | (('#FIXED' S)? AttValue) * </pre> */ private void parseDefault(String elementName, String name, String type, String enumer) throws Exception { int valueType = ATTRIBUTE_DEFAULT_SPECIFIED; String value = null; int flags = LIT_ATTRIBUTE; boolean saved = expandPE; String defaultType = null; // LIT_ATTRIBUTE forces '<' checks now (ASAP) and turns whitespace // chars to spaces (doesn't matter when that's done if it doesn't // interfere with char refs expanding to whitespace). if (!skippedPE) { flags |= LIT_ENTITY_REF; if (handler.stringInterning) { if ("CDATA" != type) { flags |= LIT_NORMALIZE; } } else { if (!"CDATA".equals(type)) { flags |= LIT_NORMALIZE; } } } expandPE = false; if (tryRead('#')) { if (tryRead("FIXED")) { defaultType = "#FIXED"; valueType = ATTRIBUTE_DEFAULT_FIXED; requireWhitespace(); value = readLiteral(flags); } else if (tryRead("REQUIRED")) { defaultType = "#REQUIRED"; valueType = ATTRIBUTE_DEFAULT_REQUIRED; } else if (tryRead("IMPLIED")) { defaultType = "#IMPLIED"; valueType = ATTRIBUTE_DEFAULT_IMPLIED; } else { error("illegal keyword for attribute default value"); } } else { value = readLiteral(flags); } expandPE = saved; setAttribute(elementName, name, type, enumer, value, valueType); if (handler.stringInterning) { if ("ENUMERATION" == type) { type = enumer; } else if ("NOTATION" == type) { type = "NOTATION " + enumer; } } else { if ("ENUMERATION".equals(type)) { type = enumer; } else if ("NOTATION".equals(type)) { type = "NOTATION " + enumer; } } if (!skippedPE) { handler.getDeclHandler().attributeDecl(elementName, name, type, defaultType, value); } } /** * Parse a conditional section. * <pre> * [61] conditionalSect ::= includeSect || ignoreSect * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' * extSubsetDecl ']]>' * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' * ignoreSectContents* ']]>' * [64] ignoreSectContents ::= Ignore * ('<![' ignoreSectContents* ']]>' Ignore )* * [65] Ignore ::= Char* - (Char* ( '<![' | ']]>') Char* ) * </pre> * <p> NOTE: the '>![' has already been read. */ private void parseConditionalSect(char[] saved) throws Exception { skipWhitespace(); if (tryRead("INCLUDE")) { skipWhitespace(); require('['); // VC: Proper Conditional Section/PE Nesting if (readBuffer != saved) { handler.verror("Illegal Conditional Section/PE nesting"); } skipWhitespace(); while (!tryRead("]]>")) { parseMarkupdecl(); skipWhitespace(); } } else if (tryRead("IGNORE")) { skipWhitespace(); require('['); // VC: Proper Conditional Section/PE Nesting if (readBuffer != saved) { handler.verror("Illegal Conditional Section/PE nesting"); } int nesting = 1; char c; expandPE = false; for (int nest = 1; nest > 0; ) { c = readCh(); switch (c) { case '<': if (tryRead("![")) { nest++; } break; case ']': if (tryRead("]>")) { nest--; } } } expandPE = true; } else { error("conditional section must begin with INCLUDE or IGNORE"); } } private void parseCharRef() throws SAXException, IOException { parseCharRef(true /* do flushDataBuffer by default */); } /** * Try to read a character reference without consuming data from buffer. * <pre> * [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';' * </pre> * <p>NOTE: the '&#' has already been read. */ private void tryReadCharRef() throws SAXException, IOException { int value = 0; char c; if (tryRead('x')) {loop1: while (true) { c = readCh(); if (c == ';') { break loop1; } else { int n = Character.digit(c, 16); if (n == -1) { error("illegal character in character reference", c, null); break loop1; } value *= 16; value += n; } } } else {loop2: while (true) { c = readCh(); if (c == ';') { break loop2; } else { int n = Character.digit(c, 10); if (n == -1) { error("illegal character in character reference", c, null); break loop2; } value *= 10; value += n; } } } // check for character refs being legal XML if ((value < 0x0020 && ! (value == '\n' || value == '\t' || value == '\r')) || (value >= 0xD800 && value <= 0xDFFF) || value == 0xFFFE || value == 0xFFFF || value > 0x0010ffff) { error("illegal XML character reference U+" + Integer.toHexString(value)); } // Check for surrogates: 00000000 0000xxxx yyyyyyyy zzzzzzzz // (1101|10xx|xxyy|yyyy + 1101|11yy|zzzz|zzzz: if (value > 0x0010ffff) { // too big for surrogate error("character reference " + value + " is too large for UTF-16", new Integer(value).toString(), null); } } /** * Read and interpret a character reference. * <pre> * [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';' * </pre> * <p>NOTE: the '&#' has already been read. */ private void parseCharRef(boolean doFlush) throws SAXException, IOException { int value = 0; char c; if (tryRead('x')) {loop1: while (true) { c = readCh(); if (c == ';') { break loop1; } else { int n = Character.digit(c, 16); if (n == -1) { error("illegal character in character reference", c, null); break loop1; } value *= 16; value += n; } } } else {loop2: while (true) { c = readCh(); if (c == ';') { break loop2; } else { int n = Character.digit(c, 10); if (n == -1) { error("illegal character in character reference", c, null); break loop2; } value *= 10; value += c - '0'; } } } // check for character refs being legal XML if ((value < 0x0020 && ! (value == '\n' || value == '\t' || value == '\r')) || (value >= 0xD800 && value <= 0xDFFF) || value == 0xFFFE || value == 0xFFFF || value > 0x0010ffff) { error("illegal XML character reference U+" + Integer.toHexString(value)); } // Check for surrogates: 00000000 0000xxxx yyyyyyyy zzzzzzzz // (1101|10xx|xxyy|yyyy + 1101|11yy|zzzz|zzzz: if (value <= 0x0000ffff) { // no surrogates needed dataBufferAppend((char) value); } else if (value <= 0x0010ffff) { value -= 0x10000; // > 16 bits, surrogate needed dataBufferAppend((char) (0xd800 | (value >> 10))); dataBufferAppend((char) (0xdc00 | (value & 0x0003ff))); } else { // too big for surrogate error("character reference " + value + " is too large for UTF-16", new Integer(value).toString(), null); } if (doFlush) { dataBufferFlush(); } } /** * Parse and expand an entity reference. * <pre> * [68] EntityRef ::= '&' Name ';' * </pre> * <p>NOTE: the '&' has already been read. * @param externalAllowed External entities are allowed here. */ private void parseEntityRef(boolean externalAllowed) throws SAXException, IOException { String name; name = readNmtoken(true); require(';'); switch (getEntityType(name)) { case ENTITY_UNDECLARED: // NOTE: XML REC describes amazingly convoluted handling for // this case. Nothing as meaningful as being a WFness error // unless the processor might _legitimately_ not have seen a // declaration ... which is what this implements. String message; message = "reference to undeclared general entity " + name; if (skippedPE && !docIsStandalone) { handler.verror(message); // we don't know this entity, and it might be external... if (externalAllowed) { handler.skippedEntity(name); } } else { error(message); } break; case ENTITY_INTERNAL: pushString(name, getEntityValue(name)); //workaround for possible input pop before marking //the buffer reading position cha
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -