123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855 |
- /* StreamSerializer.java --
- Copyright (C) 2004,2006 Free Software Foundation, Inc.
- This file is part of GNU Classpath.
- GNU Classpath is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- GNU Classpath is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library. Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module. An independent module is a module which is not derived from
- or based on this library. If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so. If you do not wish to do so, delete this
- exception statement from your version. */
- package gnu.xml.transform;
- import gnu.java.lang.CPStringBuilder;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.nio.ByteBuffer;
- import java.nio.CharBuffer;
- import java.nio.charset.Charset;
- import java.nio.charset.CharsetEncoder;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.LinkedList;
- import java.util.Map;
- import javax.xml.XMLConstants;
- import org.w3c.dom.Attr;
- import org.w3c.dom.Document;
- import org.w3c.dom.DocumentType;
- import org.w3c.dom.NamedNodeMap;
- import org.w3c.dom.Node;
- /**
- * Serializes a DOM node to an output stream.
- *
- * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
- */
- public class StreamSerializer
- {
- static final int SPACE = 0x20;
- static final int BANG = 0x21; // !
- static final int APOS = 0x27; // '
- static final int SLASH = 0x2f; // /
- static final int BRA = 0x3c; // <
- static final int KET = 0x3e; // >
- static final int EQ = 0x3d; // =
- /**
- * HTML 4.01 boolean attributes
- */
- static final Map HTML_BOOLEAN_ATTRIBUTES = new HashMap();
- static
- {
- HashSet set;
- set = new HashSet();
- set.add("nohref");
- HTML_BOOLEAN_ATTRIBUTES.put("area", set);
- set = new HashSet();
- set.add("ismap");
- HTML_BOOLEAN_ATTRIBUTES.put("img", set);
- set = new HashSet();
- set.add("declare");
- HTML_BOOLEAN_ATTRIBUTES.put("object", set);
- set = new HashSet();
- set.add("noshade");
- HTML_BOOLEAN_ATTRIBUTES.put("hr", set);
- set = new HashSet();
- set.add("compact");
- HTML_BOOLEAN_ATTRIBUTES.put("dl", set);
- HTML_BOOLEAN_ATTRIBUTES.put("ol", set);
- HTML_BOOLEAN_ATTRIBUTES.put("ul", set);
- HTML_BOOLEAN_ATTRIBUTES.put("dir", set);
- HTML_BOOLEAN_ATTRIBUTES.put("menu", set);
- set = new HashSet();
- set.add("checked");
- set.add("disabled");
- set.add("readonly");
- set.add("ismap");
- HTML_BOOLEAN_ATTRIBUTES.put("input", set);
- set = new HashSet();
- set.add("multiple");
- set.add("disabled");
- HTML_BOOLEAN_ATTRIBUTES.put("select", set);
- set = new HashSet();
- set.add("disabled");
- HTML_BOOLEAN_ATTRIBUTES.put("optgroup", set);
- set = new HashSet();
- set.add("selected");
- set.add("disabled");
- HTML_BOOLEAN_ATTRIBUTES.put("option", set);
- set = new HashSet();
- set.add("disabled");
- set.add("readonly");
- HTML_BOOLEAN_ATTRIBUTES.put("textarea", set);
- set = new HashSet();
- set.add("disabled");
- HTML_BOOLEAN_ATTRIBUTES.put("button", set);
- set = new HashSet();
- set.add("nowrap");
- HTML_BOOLEAN_ATTRIBUTES.put("th", set);
- HTML_BOOLEAN_ATTRIBUTES.put("td", set);
- set = new HashSet();
- set.add("noresize");
- HTML_BOOLEAN_ATTRIBUTES.put("frame", set);
- set = new HashSet();
- set.add("defer");
- HTML_BOOLEAN_ATTRIBUTES.put("script", set);
- }
- // HTML namespace URIs
- static final HashSet HTML_URIS = new HashSet();
- static {
- HTML_URIS.add("http://www.w3.org/1999/xhtml");
- }
- protected final String encoding;
- final Charset charset;
- final CharsetEncoder encoder;
- final int mode;
- final LinkedList namespaces;
- protected String eol;
- Collection cdataSectionElements = Collections.EMPTY_SET;
- protected boolean discardDefaultContent;
- protected boolean xmlDeclaration = true;
- // has a META element with the encoding been added?
- private boolean htmlEncoded;
- public StreamSerializer()
- {
- this(Stylesheet.OUTPUT_XML, null, null);
- }
- public StreamSerializer(String encoding)
- {
- this(Stylesheet.OUTPUT_XML, encoding, null);
- }
- public StreamSerializer(int mode, String encoding, String eol)
- {
- this.mode = mode;
- if (encoding == null)
- encoding = (mode == Stylesheet.OUTPUT_HTML) ? "ISO-8859-1" : "UTF-8";
- this.encoding = encoding.intern();
- charset = Charset.forName(this.encoding);
- encoder = charset.newEncoder();
- this.eol = (eol != null) ? eol : System.getProperty("line.separator");
- namespaces = new LinkedList();
- }
- void setCdataSectionElements(Collection c)
- {
- cdataSectionElements = c;
- }
- public void serialize(final Node node, final OutputStream out)
- throws IOException
- {
- serialize(node, out, false);
- }
- void serialize(Node node, final OutputStream out,
- boolean convertToCdata)
- throws IOException
- {
- while (node != null)
- {
- Node next = node.getNextSibling();
- doSerialize(node, out, convertToCdata);
- node = next;
- }
- }
- private void doSerialize(final Node node, final OutputStream out,
- boolean convertToCdata)
- throws IOException
- {
- if (out == null)
- throw new NullPointerException("no output stream");
- htmlEncoded = false;
- String value, prefix;
- Node children;
- String uri = node.getNamespaceURI();
- short nt = node.getNodeType();
- if (convertToCdata && nt == Node.TEXT_NODE)
- nt = Node.CDATA_SECTION_NODE;
- switch (nt)
- {
- case Node.ATTRIBUTE_NODE:
- prefix = node.getPrefix();
- if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri) ||
- XMLConstants.XMLNS_ATTRIBUTE.equals(prefix) ||
- (prefix != null && prefix.startsWith("xmlns:")))
- {
- String nsuri = node.getNodeValue();
- if (isDefined(nsuri, prefix))
- break;
- String name = node.getLocalName();
- if (name == null)
- {
- // Namespace-unaware
- name = node.getNodeName();
- int ci = name.indexOf(':');
- if (ci != -1)
- name = name.substring(ci + 1);
- }
- define(nsuri, name);
- }
- else if (uri != null && !isDefined(uri, prefix))
- {
- prefix = define(uri, prefix);
- String nsname = (prefix == null) ? "xmlns" : "xmlns:" + prefix;
- out.write(SPACE);
- out.write(encodeText(nsname));
- out.write(EQ);
- String nsvalue = "\"" + encode(uri, true, true) + "\"";
- out.write(nsvalue.getBytes(encoding));
- }
- out.write(SPACE);
- String a_nodeName = node.getNodeName();
- out.write(encodeText(a_nodeName));
- String a_nodeValue = node.getNodeValue();
- if (mode == Stylesheet.OUTPUT_HTML &&
- a_nodeName.equals(a_nodeValue) &&
- isHTMLBoolean((Attr) node, a_nodeName))
- break;
- out.write(EQ);
- value = "\"" + encode(a_nodeValue, true, true) + "\"";
- out.write(encodeText(value));
- break;
- case Node.ELEMENT_NODE:
- pushNamespaceContext();
- value = node.getNodeName();
- out.write(BRA);
- out.write(encodeText(value));
- prefix = node.getPrefix();
- if (uri != null && !isDefined(uri, prefix))
- {
- prefix = define(uri, prefix);
- String nsname = (prefix == null) ? "xmlns" : "xmlns:" + prefix;
- out.write(SPACE);
- out.write(encodeText(nsname));
- out.write(EQ);
- String nsvalue = "\"" + encode(uri, true, true) + "\"";
- out.write(encodeText(nsvalue));
- }
- NamedNodeMap attrs = node.getAttributes();
- if (attrs != null)
- {
- int len = attrs.getLength();
- for (int i = 0; i < len; i++)
- {
- Attr attr = (Attr) attrs.item(i);
- if (discardDefaultContent && !attr.getSpecified())
- {
- // NOOP
- }
- else
- serialize(attr, out, false);
- }
- }
- convertToCdata = cdataSectionElements.contains(value);
- children = node.getFirstChild();
- if (children == null)
- {
- out.write(SLASH);
- out.write(KET);
- }
- else
- {
- out.write(KET);
- serialize(children, out, convertToCdata);
- out.write(BRA);
- out.write(SLASH);
- out.write(encodeText(value));
- out.write(KET);
- }
- popNamespaceContext();
- break;
- case Node.TEXT_NODE:
- value = node.getNodeValue();
- if (!"yes".equals(node.getUserData("disable-output-escaping")) &&
- mode != Stylesheet.OUTPUT_TEXT)
- value = encode(value, false, false);
- out.write(encodeText(value));
- break;
- case Node.CDATA_SECTION_NODE:
- value = node.getNodeValue();
- // Where any instanceof of ]]> occur, split into multiple CDATA
- // sections
- int bbk = value.indexOf("]]>");
- while (bbk != -1)
- {
- String head = value.substring(0, bbk + 2);
- out.write(encodeText("<![CDATA[" + head + "]]>"));
- value = value.substring(bbk + 2);
- bbk = value.indexOf("]]>");
- }
- // Write final tail value
- out.write(encodeText("<![CDATA[" + value + "]]>"));
- break;
- case Node.COMMENT_NODE:
- value = "<!--" + node.getNodeValue() + "-->";
- out.write(encodeText(value));
- Node cp = node.getParentNode();
- if (cp != null && cp.getNodeType() == Node.DOCUMENT_NODE)
- out.write(encodeText(eol));
- break;
- case Node.DOCUMENT_NODE:
- case Node.DOCUMENT_FRAGMENT_NODE:
- if (mode == Stylesheet.OUTPUT_XML)
- {
- if ("UTF-16".equalsIgnoreCase(encoding))
- {
- out.write(0xfe);
- out.write(0xff);
- }
- if (!"yes".equals(node.getUserData("omit-xml-declaration")) &&
- xmlDeclaration)
- {
- Document doc = (node instanceof Document) ?
- (Document) node : null;
- String version = (doc != null) ? doc.getXmlVersion() : null;
- if (version == null)
- version = (String) node.getUserData("version");
- if (version == null)
- version = "1.0";
- out.write(BRA);
- out.write(0x3f);
- out.write("xml version=\"".getBytes("US-ASCII"));
- out.write(version.getBytes("US-ASCII"));
- out.write(0x22);
- if (!("UTF-8".equalsIgnoreCase(encoding)))
- {
- out.write(" encoding=\"".getBytes("US-ASCII"));
- out.write(encoding.getBytes("US-ASCII"));
- out.write(0x22);
- }
- if ((doc != null && doc.getXmlStandalone()) ||
- "yes".equals(node.getUserData("standalone")))
- out.write(" standalone=\"yes\"".getBytes("US-ASCII"));
- out.write(0x3f);
- out.write(KET);
- out.write(encodeText(eol));
- }
- // TODO warn if not outputting the declaration would be a
- // problem
- }
- else if (mode == Stylesheet.OUTPUT_HTML)
- {
- // Ensure that encoding is accessible if head element is present
- String mediaType = (String) node.getUserData("media-type");
- if (mediaType == null)
- mediaType = "text/html";
- String contentType = mediaType + "; charset=" +
- ((encoding.indexOf(' ') != -1) ?
- "\"" + encoding + "\"" :
- encoding);
- Document doc = (node instanceof Document) ? (Document) node :
- node.getOwnerDocument();
- Node html = null;
- for (Node ctx = node.getFirstChild(); ctx != null;
- ctx = ctx.getNextSibling())
- {
- if (ctx.getNodeType() == Node.ELEMENT_NODE &&
- isHTMLElement(ctx, "html"))
- {
- html = ctx;
- break;
- }
- }
- if (html != null)
- {
- Node head = null;
- for (Node ctx = html.getFirstChild(); ctx != null;
- ctx = ctx.getNextSibling())
- {
- if (isHTMLElement(ctx, "head"))
- {
- head = ctx;
- break;
- }
- }
- 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
- CPStringBuilder buf = new CPStringBuilder();
- 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();
- CPStringBuilder buf = null;
- for (int i = 0; i < len; i++)
- {
- char c = text.charAt(i);
- if (c == '<')
- {
- if (buf == null)
- buf = new CPStringBuilder(text.substring(0, i));
- buf.append("<");
- }
- else if (c == '>')
- {
- if (buf == null)
- buf = new CPStringBuilder(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 CPStringBuilder(text.substring(0, i));
- buf.append("&");
- }
- }
- else if (c == '\'' && inAttr)
- {
- if (buf == null)
- buf = new CPStringBuilder(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 CPStringBuilder(text.substring(0, i));
- buf.append(""");
- }
- else if (encodeCtl)
- {
- if (c < 0x20)
- {
- if (buf == null)
- buf = new CPStringBuilder(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;
- }
- }
- }
|