📄 xmlelement.java
字号:
* @param key Description of Parameter */ public void removeChild(String key) { if (this.ignoreCase) { key = key.toUpperCase(); } this.attributes.remove(key); } /** * Writes the XML element to a string. * * @return Description of the Returned Value */ public String toString() { StringWriter writer = new StringWriter(); this.write(writer); return writer.toString(); } /** * Writes the XML element to a writer. * * @param writer Description of Parameter */ public void write(Writer writer) { this.write(writer, 0); } /** * Writes the XML element to a writer. * * @param writer Description of Parameter * @param indent Description of Parameter */ public void write(Writer writer, int indent) { PrintWriter out = new PrintWriter(writer); for (int i = 0; i < indent; i++) { out.print(' '); } if (this.tagName == null) { this.writeEncoded(out, this.contents); return; } out.print('<'); out.print(this.tagName); if (!this.attributes.isEmpty()) { Enumeration enumeration = this.attributes.keys(); while (enumeration.hasMoreElements()) { out.print(' '); String key = (String) (enumeration.nextElement()); String value = (String) (this.attributes.get(key)); out.print(key); out.print("=\""); this.writeEncoded(out, value); out.print('"'); } } if ((this.contents != null) && (this.contents.length() > 0)) { if (this.skipLeadingWhitespace) { out.println('>'); for (int i = 0; i < indent + 4; i++) { out.print(' '); } out.println(this.contents); for (int i = 0; i < indent; i++) { out.print(' '); } } else { out.print('>'); this.writeEncoded(out, this.contents); } out.print("</"); out.print(this.tagName); out.println('>'); } else if (this.children.isEmpty()) { out.println("/>"); } else { out.println('>'); Enumeration enumeration = this.enumerateChildren(); while (enumeration.hasMoreElements()) { XMLElement child = (XMLElement) (enumeration.nextElement()); child.write(writer, indent + 4); } for (int i = 0; i < indent; i++) { out.print(' '); } out.print("</"); out.print(this.tagName); out.println('>'); } } /** * !!! Searches the content for child objects. If such objects exist, the * content is reduced to <CODE>null</CODE>. * * @param input Description of Parameter * @param contentOffset Description of Parameter * @param contentSize Description of Parameter * @param contentLineNr Description of Parameter * @exception XMLParseException Description of Exception * @see com.l2fprod.contrib.nanoxml.XMLElement#parseCharArray(char[], int, int, int[]) */ protected void scanChildren(char[] input, int contentOffset, int contentSize, int contentLineNr) throws XMLParseException { int end = contentOffset + contentSize; int offset = contentOffset; int lineNr[] = new int[1]; lineNr[0] = contentLineNr; while (offset < end) { try { offset = this.skipWhitespace(input, offset, end, lineNr); } catch (XMLParseException e) { return; } if ((input[offset] != '<') || ((input[offset + 1] == '!') && (input[offset + 2] == '['))) { return; } XMLElement child = this.createAnotherElement(); offset = child.parseCharArray(input, offset, end, lineNr); this.children.addElement(child); } } /** * Creates a new XML element. * * @return Description of the Returned Value */ protected XMLElement createAnotherElement() { return new XMLElement(this.conversionTable, this.skipLeadingWhitespace, false, this.ignoreCase); } /** * Skips a tag that don't contain any useful data: <?...?>, <!...> * and comments. * * @param input Description of Parameter * @param offset Description of Parameter * @param end Description of Parameter * @param lineNr Description of Parameter * @return the position after the tag */ protected int skipBogusTag(char[] input, int offset, int end, int[] lineNr) { int level = 1; while (offset < end) { char ch = input[offset++]; switch (ch) { case '\r': if ((offset < end) && (input[offset] == '\n')) { offset++; } lineNr[0]++; break; case '\n': lineNr[0]++; break; case '<': level++; break; case '>': level--; if (level == 0) { return offset; } break; default: } } throw this.unexpectedEndOfData(lineNr[0]); } /** * Converts &...; sequences to "normal" chars. * * @param s Description of Parameter * @param lineNr Description of Parameter * @return Description of the Returned Value */ protected String decodeString(String s, int lineNr) { StringBuffer result = new StringBuffer(s.length()); int index = 0; while (index < s.length()) { int index2 = (s + '&').indexOf('&', index); int index3 = (s + "<![CDATA[").indexOf("<![CDATA[", index); if (index2 <= index3) { result.append(s.substring(index, index2)); if (index2 == s.length()) { break; } index = s.indexOf(';', index2); if (index < 0) { result.append(s.substring(index2)); break; } String key = s.substring(index2 + 1, index); if (key.charAt(0) == '#') { if (key.charAt(1) == 'x') { result.append((char) ( Integer.parseInt(key.substring(2), 16))); } else { result.append((char) ( Integer.parseInt(key.substring(1), 10))); } } else { result.append(this.conversionTable .getProperty(key, "&" + key + ';')); } } else { int index4 = (s + "]]>").indexOf("]]>", index3 + 9); result.append(s.substring(index, index3)); result.append(s.substring(index3 + 9, index4)); index = index4 + 2; } index++; } return result.toString(); } /** * Writes a string encoded to a writer. * * @param out Description of Parameter * @param str Description of Parameter */ protected void writeEncoded(PrintWriter out, String str) { for (int i = 0; i < str.length(); i++) { char ch = str.charAt(i); switch (ch) { case '<': out.write("<"); break; case '>': out.write(">"); break; case '&': out.write("&"); break; case '"': out.write("""); break; case '\'': out.write("'"); break; case '\r': case '\n': out.write(ch); break; default: if (((int) ch < 32) || ((int) ch > 126)) { out.write("&#x"); out.write(Integer.toString((int) ch, 16)); out.write(';'); } else { out.write(ch); } } } } /** * Checks whether a character may be part of an identifier. * * @param ch Description of Parameter * @return The IdentifierChar value */ private boolean isIdentifierChar(char ch) { return (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) || ((ch >= '0') && (ch <= '9')) || (".-_:".indexOf(ch) >= 0)); } /** * Parses an XML definition starting at <I>offset</I> . * * @param input Description of Parameter * @param offset Description of Parameter * @param end Description of Parameter * @param currentLineNr Description of Parameter * @return the offset of the array following the * XML data (<= end) * @exception XMLParseException Description of Exception */ private int parseCharArray(char[] input, int offset, int end, int[] currentLineNr) throws XMLParseException { this.lineNr = currentLineNr[0]; this.tagName = null; this.contents = null; this.attributes = new Properties(); this.children = new Vector(); try { offset = this.skipWhitespace(input, offset, end, currentLineNr); } catch (XMLParseException e) { return offset; } offset = this.skipPreamble(input, offset, end, currentLineNr); offset = this.scanTagName(input, offset, end, currentLineNr); this.lineNr = currentLineNr[0]; offset = this.scanAttributes(input, offset, end, currentLineNr); int[] contentOffset = new int[1]; int[] contentSize = new int[1]; int contentLineNr = currentLineNr[0]; offset = this.scanContent(input, offset, end, contentOffset, contentSize, currentLineNr); if (contentSize[0] > 0) { this.scanChildren(input, contentOffset[0], contentSize[0], contentLineNr); if (this.children.size() > 0) { this.contents = null; } else { this.processContents(input, contentOffset[0], contentSize[0], contentLineNr); for (int i = 0; i < contentSize[0]; i++) { if (input[contentOffset[0] + i] > ' ') { return offset; } } this.contents = null; } } return offset; } /** * Decodes the entities in the contents and, if skipLeadingWhitespace is * <CODE>true</CODE>, removes extraneous whitespaces after newlines and * convert those newlines into spaces. * * @param input Description of Parameter * @param contentOffset Description of Parameter * @param contentSize Description of Parameter * @param contentLineNr Description of Parameter * @exception XMLParseException Description of Exception * @see com.l2fprod.contrib.nanoxml.XMLElement#decodeString */ private void processContents(char[] input, int contentOffset, int contentSize, int contentLineNr) throws XMLParseException { int[] lineNr = new int[1]; lineNr[0] = contentLineNr; if (!this.skipLeadingWhitespace) { String str = new String(input, contentOffset, contentSize); this.contents = this.decodeString(str, lineNr[0]); return; } StringBuffer result = new StringBuffer(contentSize); int end = contentSize + contentOffset; for (int i = contentOffset; i < end; i++) { char ch = input[i]; // The end of the contents is always a < character, so there's // no danger for bounds violation while ((ch == '\r') || (ch == '\n')) { lineNr[0]++; result.append(ch); i++; ch = input[i]; if (ch != '\n') { result.append(ch); } do { i++; ch = input[i]; } while ((ch == ' ') || (ch == '\t')); } if (i < end) { result.append(ch); } } this.contents = this.decodeString(result.toString(), lineNr[0]); } /** * Scans the attributes of the object. * * @param input Description of Parameter * @param offset Description of Parameter * @param end Description of Parameter * @param lineNr Description of Parameter * @return the offset in the string following * the attributes, so that input[offset] in { '/', '>' } * @exception XMLParseException Description of Exception * @see com.l2fprod.contrib.nanoxml.XMLElement#scanOneAttribute */ private int scanAttributes(char[] input, int offset, int end, int[] lineNr) throws XMLParseException { // String key; // String value; for (; ; ) { offset = this.skipWhitespace(input, offset, end, lineNr); char ch = input[offset]; if ((ch == '/') || (ch == '>')) { break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -