📄 streamserializer.java
字号:
if (head != null) { Node meta = null; Node metaContent = null; for (Node ctx = head.getFirstChild(); ctx != null; ctx = ctx.getNextSibling()) { if (isHTMLElement(ctx, "meta")) { NamedNodeMap metaAttrs = ctx.getAttributes(); int len = metaAttrs.getLength(); String httpEquiv = null; Node content = null; for (int i = 0; i < len; i++) { Node attr = metaAttrs.item(i); String attrName = attr.getNodeName(); if ("http-equiv".equalsIgnoreCase(attrName)) httpEquiv = attr.getNodeValue(); else if ("content".equalsIgnoreCase(attrName)) content = attr; } if ("Content-Type".equalsIgnoreCase(httpEquiv)) { meta = ctx; metaContent = content; break; } } } if (meta == null) { meta = doc.createElement("meta"); // Insert first Node first = head.getFirstChild(); if (first == null) head.appendChild(meta); else head.insertBefore(meta, first); Node metaHttpEquiv = doc.createAttribute("http-equiv"); meta.getAttributes().setNamedItem(metaHttpEquiv); metaHttpEquiv.setNodeValue("Content-Type"); } if (metaContent == null) { metaContent = doc.createAttribute("content"); meta.getAttributes().setNamedItem(metaContent); } metaContent.setNodeValue(contentType); htmlEncoded = true; } } } children = node.getFirstChild(); if (children != null) serialize(children, out, convertToCdata); break; case Node.DOCUMENT_TYPE_NODE: DocumentType doctype = (DocumentType) node; out.write(BRA); out.write(BANG); out.write(encodeText("DOCTYPE ")); value = doctype.getNodeName(); out.write(encodeText(value)); String publicId = doctype.getPublicId(); if (publicId != null) { out.write(encodeText(" PUBLIC ")); out.write(APOS); out.write(encodeText(publicId)); out.write(APOS); } String systemId = doctype.getSystemId(); if (systemId != null) { out.write(encodeText(" SYSTEM ")); out.write(APOS); out.write(encodeText(systemId)); out.write(APOS); } String internalSubset = doctype.getInternalSubset(); if (internalSubset != null) { out.write(encodeText(internalSubset)); } out.write(KET); out.write(eol.getBytes(encoding)); break; case Node.ENTITY_REFERENCE_NODE: value = "&" + node.getNodeValue() + ";"; out.write(encodeText(value)); break; case Node.PROCESSING_INSTRUCTION_NODE: value = "<?" + node.getNodeName() + " " + node.getNodeValue() + "?>"; out.write(encodeText(value)); Node pp = node.getParentNode(); if (pp != null && pp.getNodeType() == Node.DOCUMENT_NODE) { out.write(encodeText(eol)); } break; default: System.err.println("Unhandled node type: "+nt); } } boolean isHTMLElement(Node node, String name) { if (node.getNodeType() != Node.ELEMENT_NODE) return false; String localName = node.getLocalName(); if (localName == null) localName = node.getNodeName(); if (!name.equalsIgnoreCase(localName)) return false; String uri = node.getNamespaceURI(); return (uri == null || HTML_URIS.contains(uri)); } boolean isDefined(String uri, String prefix) { if (XMLConstants.XML_NS_URI.equals(uri)) return "xml".equals(prefix); if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri)) return "xmlns".equals(prefix); if (prefix == null) prefix = ""; for (Iterator i = namespaces.iterator(); i.hasNext(); ) { Map ctx = (Map) i.next(); String val = (String) ctx.get(uri); if (val != null && val.equals(prefix)) return true; } return false; } void pushNamespaceContext() { namespaces.addFirst(new HashMap()); } String define(String uri, String prefix) { if (namespaces.isEmpty()) return prefix; HashMap ctx = (HashMap) namespaces.getFirst(); while (ctx.containsValue(prefix)) { // Fabricate new prefix prefix = prefix + "_"; } ctx.put(uri, prefix); return prefix; } void popNamespaceContext() { namespaces.removeFirst(); } final byte[] encodeText(String text) throws IOException { encoder.reset(); boolean htmlNeedingEncoding = (mode == Stylesheet.OUTPUT_HTML && !htmlEncoded); if (!encoder.canEncode(text) || htmlNeedingEncoding) { // Check each character StringBuffer buf = new StringBuffer(); int len = text.length(); for (int i = 0; i < len; i++) { char c = text.charAt(i); if (!encoder.canEncode(c)) { // Replace with character entity reference String hex = Integer.toHexString((int) c); buf.append("&#x"); buf.append(hex); buf.append(';'); } else if (htmlNeedingEncoding) { String entityName = getHTMLCharacterEntity(c); if (entityName != null) { buf.append('&'); buf.append(entityName); buf.append(';'); } else buf.append(c); } else buf.append(c); } text = buf.toString(); } ByteBuffer encoded = encoder.encode(CharBuffer.wrap(text)); int len = encoded.limit() - encoded.position(); if (encoded.hasArray()) { byte[] ret = encoded.array(); if (ret.length > len) { // Why? byte[] ret2 = new byte[len]; System.arraycopy(ret, 0, ret2, 0, len); ret = ret2; } return ret; } encoded.flip(); byte[] ret = new byte[len]; encoded.get(ret, 0, len); return ret; } String encode(String text, boolean encodeCtl, boolean inAttr) { int len = text.length(); StringBuffer buf = null; for (int i = 0; i < len; i++) { char c = text.charAt(i); if (c == '<') { if (buf == null) buf = new StringBuffer(text.substring(0, i)); buf.append("<"); } else if (c == '>') { if (buf == null) buf = new StringBuffer(text.substring(0, i)); buf.append(">"); } else if (c == '&') { if (mode == Stylesheet.OUTPUT_HTML && (i + 1) < len && text.charAt(i + 1) == '{') { if (buf != null) buf.append(c); } else { if (buf == null) buf = new StringBuffer(text.substring(0, i)); buf.append("&"); } } else if (c == '\'' && inAttr) { if (buf == null) buf = new StringBuffer(text.substring(0, i)); if (mode == Stylesheet.OUTPUT_HTML) // HTML does not define ', use character entity ref buf.append("'"); else buf.append("'"); } else if (c == '"' && inAttr) { if (buf == null) buf = new StringBuffer(text.substring(0, i)); buf.append("""); } else if (encodeCtl) { if (c < 0x20) { if (buf == null) buf = new StringBuffer(text.substring(0, i)); buf.append('&'); buf.append('#'); buf.append((int) c); buf.append(';'); } else if (buf != null) buf.append(c); } else if (buf != null) buf.append(c); } return (buf == null) ? text : buf.toString(); } String toString(Node node) { ByteArrayOutputStream out = new ByteArrayOutputStream(); try { serialize(node, out); return new String(out.toByteArray(), encoding); } catch (IOException e) { throw new RuntimeException(e.getMessage()); } } boolean isHTMLBoolean(Attr attr, String attrName) { attrName = attrName.toLowerCase(); Node element = attr.getOwnerElement(); String elementName = element.getLocalName(); if (elementName == null) { elementName = element.getNodeName(); } elementName = elementName.toLowerCase(); Collection attributes = (Collection) HTML_BOOLEAN_ATTRIBUTES.get(elementName); return (attributes != null && attributes.contains(attrName)); } static String getHTMLCharacterEntity(char c) { // Hardcode these here to avoid loading the HTML DTD switch (c) { case 160: return "nbsp"; case 161: return "iexcl"; case 162: return "cent"; case 163: return "pound"; case 164: return "curren"; case 165: return "yen"; case 166: return "brvbar"; case 167: return "sect"; case 168: return "uml"; case 169: return "copy"; case 170: return "ordf"; case 171: return "laquo"; case 172: return "not"; case 173: return "shy"; case 174: return "reg"; case 175: return "macr"; case 176: return "deg"; case 177: return "plusmn"; case 178: return "sup2"; case 179: return "sup3"; case 180: return "acute"; case 181: return "micro"; case 182: return "para"; case 183: return "middot"; case 184: return "cedil"; case 185: return "sup1"; case 186: return "ordm"; case 187: return "raquo"; case 188: return "frac14"; case 189: return "frac12"; case 190: return "frac34"; case 191: return "iquest"; case 192: return "Agrave"; case 193: return "Aacute"; case 194: return "Acirc"; case 195: return "Atilde"; case 196: return "Auml"; case 197: return "Aring"; case 198: return "AElig"; case 199: return "Ccedil"; case 200: return "Egrave"; case 201: return "Eacute"; case 202: return "Ecirc"; case 203: return "Euml"; case 204: return "Igrave"; case 205: return "Iacute"; case 206: return "Icirc"; case 207: return "Iuml"; case 208: return "ETH"; case 209: return "Ntilde"; case 210: return "Ograve"; case 211: return "Oacute"; case 212: return "Ocirc"; case 213: return "Otilde"; case 214: return "Ouml"; case 215: return "times"; case 216: return "Oslash"; case 217: return "Ugrave"; case 218: return "Uacute"; case 219: return "Ucirc"; case 220: return "Uuml"; case 221: return "Yacute"; case 222: return "THORN"; case 223: return "szlig"; case 224: return "agrave"; case 225: return "aacute"; case 226: return "acirc"; case 227: return "atilde"; case 228: return "auml"; case 229: return "aring"; case 230: return "aelig"; case 231: return "ccedil"; case 232: return "egrave"; case 233: return "eacute"; case 234: return "ecirc"; case 235: return "euml"; case 236: return "igrave"; case 237: return "iacute"; case 238: return "icirc"; case 239: return "iuml"; case 240: return "eth"; case 241: return "ntilde"; case 242: return "ograve"; case 243: return "oacute"; case 244: return "ocirc"; case 245: return "otilde"; case 246: return "ouml"; case 247: return "divide"; case 248: return "oslash"; case 249: return "ugrave"; case 250: return "uacute"; case 251: return "ucirc"; case 252: return "uuml"; case 253: return "yacute"; case 254: return "thorn"; case 255: return "yuml"; default: return null; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -