serializertohtml.java
来自「java jdk 1.4的源码」· Java 代码 · 共 1,368 行 · 第 1/3 页
JAVA
1,368 行
* a document. * * @param format The output format to use */ public void setOutputFormat(Properties format) { m_specialEscapeURLs = OutputProperties.getBooleanProperty(OutputProperties.S_USE_URL_ESCAPING, format); m_omitMetaTag = OutputProperties.getBooleanProperty(OutputProperties.S_OMIT_META_TAG, format); super.setOutputFormat(format); } /** * Tells if the formatter should use special URL escaping. * * @return True if URLs should be specially escaped with the %xx form. */ public boolean getSpecialEscapeURLs() { return m_specialEscapeURLs; } /** * Tells if the formatter should omit the META tag. * * @return True if the META tag should be omitted. */ public boolean getOmitMetaTag() { return m_omitMetaTag; } /** * Get a description of the given element. * * @param name non-null name of element, case insensitive. * * @return non-null reference to ElemDesc, which may be m_dummy if no * element description matches the given name. */ ElemDesc getElemDesc(String name) { if (null != name) { Object obj = m_elementFlags.get(name); if (null != obj) return (ElemDesc) obj; } return m_dummy; } /** * Default constructor. */ public SerializerToHTML() { super(); m_charInfo = m_htmlcharInfo; } /** The name of the current element. */ private String m_currentElementName = null; /** * Receive notification of the beginning of a document. * * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * * @throws org.xml.sax.SAXException */ public void startDocument() throws org.xml.sax.SAXException { m_needToOutputDocTypeDecl = true; m_startNewLine = false; m_shouldNotWriteXMLHeader = true; if (true == m_needToOutputDocTypeDecl) { if ((null != m_doctypeSystem) || (null != m_doctypePublic)) { accum("<!DOCTYPE HTML"); if (null != m_doctypePublic) { accum(" PUBLIC \""); accum(m_doctypePublic); accum("\""); } if (null != m_doctypeSystem) { if (null == m_doctypePublic) accum(" SYSTEM \""); else accum(" \""); accum(m_doctypeSystem); accum("\""); } accum(">"); outputLineSep(); } } m_needToOutputDocTypeDecl = false; } /** * Receive notification of the beginning of an element. * * * @param namespaceURI * @param localName * @param name The element type name. * @param atts The attributes attached to the element, if any. * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see #endElement * @see org.xml.sax.AttributeList */ public void startElement( String namespaceURI, String localName, String name, Attributes atts) throws org.xml.sax.SAXException { // System.out.println("SerializerToHTML#startElement("+namespaceURI+", "+localName+", "+name+", ...);"); if (null != namespaceURI && namespaceURI.length() > 0) { super.startElement(namespaceURI, localName, name, atts); return; } boolean savedDoIndent = m_doIndent; boolean noLineBreak; writeParentTagEnd(); pushState( namespaceURI, localName, m_cdataSectionNames, m_cdataSectionStates); // pushState(namespaceURI, localName, m_format.getNonEscapingElements(), // m_disableOutputEscapingStates); ElemDesc elemDesc = getElemDesc(name); // ElemDesc parentElemDesc = getElemDesc(m_currentElementName); boolean isBlockElement = elemDesc.is(ElemDesc.BLOCK); boolean isHeadElement = elemDesc.is(ElemDesc.HEADELEM); // boolean isWhiteSpaceSensitive = elemDesc.is(ElemDesc.WHITESPACESENSITIVE); if (m_ispreserve) m_ispreserve = false; else if (m_doIndent && (null != m_currentElementName) && (!m_inBlockElem || isBlockElement) /* && !isWhiteSpaceSensitive */ ) { m_startNewLine = true; indent(m_currentIndent); } m_inBlockElem = !isBlockElement; m_isRawStack.push(elemDesc.is(ElemDesc.RAW)); m_currentElementName = name; // m_parents.push(m_currentElementName); this.accum('<'); this.accum(name); int nAttrs = atts.getLength(); for (int i = 0; i < nAttrs; i++) { processAttribute(atts.getQName(i), elemDesc, atts.getValue(i)); } // Flag the current element as not yet having any children. openElementForChildren(); m_currentIndent += this.m_indentAmount; m_isprevtext = false; m_doIndent = savedDoIndent; if (isHeadElement) { writeParentTagEnd(); if (!m_omitMetaTag) { if (m_doIndent) indent(m_currentIndent); accum( "<META http-equiv=\"Content-Type\" content=\"text/html; charset="); // String encoding = Encodings.getMimeEncoding(m_encoding).toLowerCase(); String encoding = Encodings.getMimeEncoding(m_encoding); accum(encoding); accum('"'); accum('>'); } } } /** * Receive notification of the end of an element. * * * @param namespaceURI * @param localName * @param name The element type name * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. */ public void endElement(String namespaceURI, String localName, String name) throws org.xml.sax.SAXException { // System.out.println("SerializerToHTML#endElement("+namespaceURI+", "+localName+", "+name+");"); if (null != namespaceURI && namespaceURI.length() > 0) { super.endElement(namespaceURI, localName, name); return; } m_currentIndent -= this.m_indentAmount; boolean hasChildNodes = childNodesWereAdded(); // System.out.println(m_currentElementName); // m_parents.pop(); m_isRawStack.pop(); ElemDesc elemDesc = getElemDesc(name); // ElemDesc parentElemDesc = getElemDesc(m_currentElementName); boolean isBlockElement = elemDesc.is(ElemDesc.BLOCK); boolean shouldIndent = false; if (m_ispreserve) { m_ispreserve = false; } else if (m_doIndent && (!m_inBlockElem || isBlockElement)) { m_startNewLine = true; shouldIndent = true; // indent(m_currentIndent); } m_inBlockElem = !isBlockElement; if (hasChildNodes) { if (shouldIndent) indent(m_currentIndent); this.accum("</"); this.accum(name); this.accum('>'); m_currentElementName = name; } else { if (!elemDesc.is(ElemDesc.EMPTY)) { this.accum('>'); // As per Dave/Paul recommendation 12/06/2000 // if (shouldIndent) // indent(m_currentIndent); this.accum('<'); this.accum('/'); this.accum(name); this.accum('>'); } else { this.accum('>'); } } if (elemDesc.is(ElemDesc.WHITESPACESENSITIVE)) m_ispreserve = true; if (hasChildNodes) { if (!m_preserves.isEmpty()) m_preserves.pop(); } m_isprevtext = false; // m_disableOutputEscapingStates.pop(); m_cdataSectionStates.pop(); } /** * Process an attribute. * @param name The name of the attribute. * @param elemDesc non-null reference to the owning element description. * @param value The value of the attribute. * * @throws org.xml.sax.SAXException */ protected void processAttribute( String name, ElemDesc elemDesc, String value) throws org.xml.sax.SAXException { this.accum(' '); if (((value.length() == 0) || value.equalsIgnoreCase(name)) && elemDesc.isAttrFlagSet(name, ElemDesc.ATTREMPTY)) { this.accum(name); } else { this.accum(name); this.accum('='); this.accum('\"'); if (elemDesc.isAttrFlagSet(name, ElemDesc.ATTRURL)) writeAttrURI(value, m_specialEscapeURLs); else writeAttrString(value, this.m_encoding); this.accum('\"'); } } /** * Tell if a character is an ASCII digit. */ private boolean isASCIIDigit(char c) { return (c >= '0' && c <= '9'); } /** * Make an integer into an HH hex value. * Does no checking on the size of the input, since this * is only meant to be used locally by writeAttrURI. * * @param i must be a value less than 255. * * @return should be a two character string. */ private String makeHHString(int i) { String s = Integer.toHexString(i).toUpperCase(); if(s.length() == 1) { s = "0"+s; } return s; } /** * Dmitri Ilyin: Makes sure if the String is HH encoded sign. * @param str must be 2 characters long * * @return true or false */ private boolean isHHSign(String str) { boolean sign = true; try { char r = (char)Integer.parseInt(str,16); } catch (NumberFormatException e) { sign = false; } return sign; } /** * Write the specified <var>string</var> after substituting non ASCII characters, * with <CODE>%HH</CODE>, where HH is the hex of the byte value. * * @param string String to convert to XML format. * @param doURLEscaping True if we should try to encode as * per http://www.ietf.org/rfc/rfc2396.txt. * * @throws org.xml.sax.SAXException if a bad surrogate pair is detected. */ public void writeAttrURI(String string, boolean doURLEscaping) throws org.xml.sax.SAXException { // http://www.ietf.org/rfc/rfc2396.txt says: // A URI is always in an "escaped" form, since escaping or unescaping a // completed URI might change its semantics. Normally, the only time // escape encodings can safely be made is when the URI is being created // from its component parts; each component may have its own set of // characters that are reserved, so only the mechanism responsible for // generating or interpreting that component can determine whether or // not escaping a character will change its semantics. Likewise, a URI // must be separated into its components before the escaped characters // within those components can be safely decoded. // // ...So we do our best to do limited escaping of the URL, without // causing damage. If the URL is already properly escaped, in theory, this // function should not change the string value. char[] stringArray = string.toCharArray(); int len = stringArray.length; for (int i = 0; i < len; i++) { char ch = stringArray[i]; if ((ch < 32) || (ch > 126)) { if (doURLEscaping) { // Encode UTF16 to UTF8. // Reference is Unicode, A Primer, by Tony Graham. // Page 92. // Note that Kay doesn't escape 0x20... // if(ch == 0x20) // Not sure about this... -sb // { // accum(ch); // } // else if(ch <= 0x7F) { accum('%'); accum(makeHHString(ch)); } else if(ch <= 0x7FF) { // Clear low 6 bits before rotate, put high 4 bits in low byte, // and set two high bits. int high = (ch >> 6) | 0xC0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?