1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License. 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.xml.parsers; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 20c36982772a413bb14eb6d865013aac03544441d1Jesse Wilsonimport java.net.URL; 21c36982772a413bb14eb6d865013aac03544441d1Jesse Wilsonimport java.net.URLConnection; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.xml.parsers.DocumentBuilder; 23086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilsonimport libcore.io.IoUtils; 24bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilsonimport org.apache.harmony.xml.dom.CDATASectionImpl; 257365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport org.apache.harmony.xml.dom.DOMImplementationImpl; 26bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilsonimport org.apache.harmony.xml.dom.DocumentImpl; 278b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilsonimport org.apache.harmony.xml.dom.DocumentTypeImpl; 28bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilsonimport org.apache.harmony.xml.dom.TextImpl; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.kxml2.io.KXmlParser; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.Attr; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.DOMImplementation; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.Document; 33bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilsonimport org.w3c.dom.DocumentType; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.Element; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.Node; 36af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughesimport org.w3c.dom.Text; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.EntityResolver; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.ErrorHandler; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.InputSource; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.SAXException; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.SAXParseException; 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.helpers.LocatorImpl; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 470463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson * Builds a DOM using KXmlParser. 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectclass DocumentBuilderImpl extends DocumentBuilder { 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 51bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson private static DOMImplementationImpl dom = DOMImplementationImpl.getInstance(); 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 536bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes private boolean coalescing; 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private EntityResolver entityResolver; 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private ErrorHandler errorHandler; 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean ignoreComments; 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean ignoreElementContentWhitespace; 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean namespaceAware; 5981bcd5c1f677de9c79155c87bcfbfc5896920403Jesse Wilson // adding a new field? don't forget to update reset(). 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6181bcd5c1f677de9c79155c87bcfbfc5896920403Jesse Wilson @Override public void reset() { 6281bcd5c1f677de9c79155c87bcfbfc5896920403Jesse Wilson coalescing = false; 6381bcd5c1f677de9c79155c87bcfbfc5896920403Jesse Wilson entityResolver = null; 6481bcd5c1f677de9c79155c87bcfbfc5896920403Jesse Wilson errorHandler = null; 6581bcd5c1f677de9c79155c87bcfbfc5896920403Jesse Wilson ignoreComments = false; 6681bcd5c1f677de9c79155c87bcfbfc5896920403Jesse Wilson ignoreElementContentWhitespace = false; 6781bcd5c1f677de9c79155c87bcfbfc5896920403Jesse Wilson namespaceAware = false; 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DOMImplementation getDOMImplementation() { 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return dom; 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isNamespaceAware() { 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return namespaceAware; 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isValidating() { 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Document newDocument() { 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return dom.createDocument(null, null, null); 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Document parse(InputSource source) throws SAXException, IOException { 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (source == null) { 93086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson throw new IllegalArgumentException("source == null"); 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 95f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 96bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson String namespaceURI = null; 97bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson String qualifiedName = null; 98bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson DocumentType doctype = null; 995213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson String inputEncoding = source.getEncoding(); 1005213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson String systemId = source.getSystemId(); 1015213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson DocumentImpl document = new DocumentImpl( 1025213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson dom, namespaceURI, qualifiedName, doctype, inputEncoding); 1035213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson document.setDocumentURI(systemId); 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 105086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson KXmlParser parser = new KXmlParser(); 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1071ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson parser.keepNamespaceAttributes(); 1085213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, namespaceAware); 1095213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (source.getByteStream() != null) { 1115213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson parser.setInput(source.getByteStream(), inputEncoding); 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (source.getCharacterStream() != null) { 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parser.setInput(source.getCharacterStream()); 1145213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson } else if (systemId != null) { 1155213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson URL url = new URL(systemId); 116c36982772a413bb14eb6d865013aac03544441d1Jesse Wilson URLConnection urlConnection = url.openConnection(); 117c36982772a413bb14eb6d865013aac03544441d1Jesse Wilson urlConnection.connect(); 1185213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson // TODO: if null, extract the inputEncoding from the Content-Type header? 1195213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson parser.setInput(urlConnection.getInputStream(), inputEncoding); 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 121086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson throw new SAXParseException("InputSource needs a stream, reader or URI", null); 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 124086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson if (parser.nextToken() == XmlPullParser.END_DOCUMENT) { 125086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson throw new SAXParseException("Unexpected end of document", null); 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parse(parser, document, document, XmlPullParser.END_DOCUMENT); 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parser.require(XmlPullParser.END_DOCUMENT, null, null); 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (XmlPullParserException ex) { 132086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson if (ex.getDetail() instanceof IOException) { 133086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson throw (IOException) ex.getDetail(); 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 135086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson if (ex.getDetail() instanceof RuntimeException) { 136086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson throw (RuntimeException) ex.getDetail(); 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 138f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project LocatorImpl locator = new LocatorImpl(); 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project locator.setPublicId(source.getPublicId()); 1425213a38431ea28c97d29e76c5b2d8e156c2d1705Jesse Wilson locator.setSystemId(systemId); 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project locator.setLineNumber(ex.getLineNumber()); 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project locator.setColumnNumber(ex.getColumnNumber()); 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 146086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson SAXParseException newEx = new SAXParseException(ex.getMessage(), locator); 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (errorHandler != null) { 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project errorHandler.error(newEx); 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw newEx; 153086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson } finally { 154086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson IoUtils.closeQuietly(parser); 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return document; 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implements the whole parsing of the XML document. The XML pull parser is 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * actually more of a tokenizer, and we are doing a classical recursive 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descent parsing (the method invokes itself for XML elements). Our 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * approach to parsing does accept some illegal documents (more than one 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * root element, for example). The assumption is that the DOM implementation 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * throws the proper exceptions in these cases. 167f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param parser The XML pull parser we're reading from. 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param document The document we're building. 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param node The node we're currently on (initially the document itself). 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param endToken The token that will end this recursive call. Either 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * XmlPullParser.END_DOCUMENT or XmlPullParser.END_TAG. 173f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws XmlPullParserException If a parsing error occurs. 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException If a general IO error occurs. 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 177086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson private void parse(KXmlParser parser, DocumentImpl document, Node node, 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int endToken) throws XmlPullParserException, IOException { 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int token = parser.getEventType(); 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The main parsing loop. The precondition is that we are already on the 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * token to be processed. This holds for each iteration of the loop, so 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the inner statements have to ensure that (in particular the recursive 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * call). 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (token != endToken && token != XmlPullParser.END_DOCUMENT) { 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (token == XmlPullParser.PROCESSING_INSTRUCTION) { 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Found a processing instructions. We need to split the token 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * text at the first whitespace character. 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String text = parser.getText(); 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int dot = text.indexOf(' '); 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String target = (dot != -1 ? text.substring(0, dot) : text); 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String data = (dot != -1 ? text.substring(dot + 1) : ""); 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project node.appendChild(document.createProcessingInstruction(target, 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project data)); 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (token == XmlPullParser.DOCDECL) { 204086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson String name = parser.getRootElementName(); 205086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson String publicId = parser.getPublicId(); 206086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson String systemId = parser.getSystemId(); 207086fd0244a54fa5ecf13ea66d49b22b36d7d456eJesse Wilson document.appendChild(new DocumentTypeImpl(document, name, publicId, systemId)); 208f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (token == XmlPullParser.COMMENT) { 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Found a comment. We simply take the token text, but we only 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * create a node if the client wants to see comments at all. 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!ignoreComments) { 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project node.appendChild(document.createComment(parser.getText())); 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (token == XmlPullParser.IGNORABLE_WHITESPACE) { 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 21903d1c3023ed8ff85ecb0a72d4f5615e6f81e31f6Jesse Wilson * Found some ignorable whitespace. We only add it if the client 22003d1c3023ed8ff85ecb0a72d4f5615e6f81e31f6Jesse Wilson * wants to see whitespace. Whitespace before and after the 22103d1c3023ed8ff85ecb0a72d4f5615e6f81e31f6Jesse Wilson * document element is always ignored. 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 22303d1c3023ed8ff85ecb0a72d4f5615e6f81e31f6Jesse Wilson if (!ignoreElementContentWhitespace && document != node) { 224bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson appendText(document, node, token, parser.getText()); 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2266bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes } else if (token == XmlPullParser.TEXT || token == XmlPullParser.CDSECT) { 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 2286bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes * Found a piece of text (possibly encoded as a CDATA section). 2296bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes * That's the easiest case. We simply take it and create a new text node, 2306bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes * or merge with an adjacent text node. 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 232bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson appendText(document, node, token, parser.getText()); 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (token == XmlPullParser.ENTITY_REF) { 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Found an entity reference. If an entity resolver is 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * installed, we replace it by text (if possible). Otherwise we 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * add an entity reference node. 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String entity = parser.getName(); 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (entityResolver != null) { 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // TODO Implement this... 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2450463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson String resolved = resolvePredefinedOrCharacterEntity(entity); 2460463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson if (resolved != null) { 2470463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson appendText(document, node, token, resolved); 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project node.appendChild(document.createEntityReference(entity)); 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (token == XmlPullParser.START_TAG) { 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Found an element start tag. We create an element node with 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the proper info and attributes. We then invoke parse() 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * recursively to handle the next level of nesting. When we 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * return from this call, we check that we are on the proper 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * element end tag. The whole handling differs somewhat 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * depending on whether the parser is namespace-aware or not. 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (namespaceAware) { 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Collect info for element node 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String namespace = parser.getNamespace(); 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = parser.getName(); 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String prefix = parser.getPrefix(); 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ("".equals(namespace)) { 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project namespace = null; 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 269f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Create element node and wire it correctly 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Element element = document.createElementNS(namespace, name); 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project element.setPrefix(prefix); 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project node.appendChild(element); 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < parser.getAttributeCount(); i++) { 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Collect info for a single attribute node 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String attrNamespace = parser.getAttributeNamespace(i); 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String attrPrefix = parser.getAttributePrefix(i); 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String attrName = parser.getAttributeName(i); 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String attrValue = parser.getAttributeValue(i); 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ("".equals(attrNamespace)) { 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attrNamespace = null; 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 285f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Create attribute node and wire it correctly 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Attr attr = document.createAttributeNS(attrNamespace, attrName); 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attr.setPrefix(attrPrefix); 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attr.setValue(attrValue); 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project element.setAttributeNodeNS(attr); 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 292f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Recursive descent 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project token = parser.nextToken(); 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parse(parser, document, element, XmlPullParser.END_TAG); 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Expect the element's end tag here 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parser.require(XmlPullParser.END_TAG, namespace, name); 299f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Collect info for element node 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = parser.getName(); 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Create element node and wire it correctly 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Element element = document.createElement(name); 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project node.appendChild(element); 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < parser.getAttributeCount(); i++) { 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Collect info for a single attribute node 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String attrName = parser.getAttributeName(i); 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String attrValue = parser.getAttributeValue(i); 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Create attribute node and wire it correctly 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Attr attr = document.createAttribute(attrName); 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attr.setValue(attrValue); 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project element.setAttributeNode(attr); 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Recursive descent 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project token = parser.nextToken(); 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parse(parser, document, element, XmlPullParser.END_TAG); 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Expect the element's end tag here 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parser.require(XmlPullParser.END_TAG, "", name); 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project token = parser.nextToken(); 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 3326bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes /** 333bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson * @param token the XML pull parser token type, such as XmlPullParser.CDSECT 334bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson * or XmlPullParser.ENTITY_REF. 335f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes */ 336bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson private void appendText(DocumentImpl document, Node parent, int token, String text) { 337af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes // Ignore empty runs. 3380463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson if (text.isEmpty()) { 339af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes return; 340af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes } 341af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes // Merge with any previous text node if possible. 3420463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson if (coalescing || token != XmlPullParser.CDSECT) { 343bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson Node lastChild = parent.getLastChild(); 3446bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes if (lastChild != null && lastChild.getNodeType() == Node.TEXT_NODE) { 3456bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes Text textNode = (Text) lastChild; 3465e60d541ae2a4085f4c6f3739c6cff84469bc052Jesse Wilson textNode.appendData(text); 3476bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes return; 3486bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes } 349af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes } 350af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes // Okay, we really do need a new text node 351bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson parent.appendChild(token == XmlPullParser.CDSECT 352bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson ? new CDATASectionImpl(document, text) 353bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson : new TextImpl(document, text)); 354af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes } 355af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEntityResolver(EntityResolver resolver) { 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project entityResolver = resolver; 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setErrorHandler(ErrorHandler handler) { 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project errorHandler = handler; 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Controls whether this DocumentBuilder ignores comments. 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setIgnoreComments(boolean value) { 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ignoreComments = value; 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 3736bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes public void setCoalescing(boolean value) { 3746bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes coalescing = value; 3756bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes } 3766bcf32ab404c39b85d25430f6df16503ef3526cfElliott Hughes 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Controls whether this DocumentBuilder ignores element content whitespace. 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setIgnoreElementContentWhitespace(boolean value) { 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ignoreElementContentWhitespace = value; 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Controls whether this DocumentBuilder is namespace-aware. 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setNamespaceAware(boolean value) { 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project namespaceAware = value; 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3920463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson * Returns the replacement text or null if {@code entity} isn't predefined. 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 3940463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson private String resolvePredefinedOrCharacterEntity(String entityName) { 395af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes // Character references, section 4.1 of the XML specification. 3960463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson if (entityName.startsWith("#x")) { 3970463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson return resolveCharacterReference(entityName.substring(2), 16); 3980463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson } else if (entityName.startsWith("#")) { 3990463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson return resolveCharacterReference(entityName.substring(1), 10); 400af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes } 401af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes // Predefined entities, section 4.6 of the XML specification. 4020463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson if ("lt".equals(entityName)) { 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return "<"; 4040463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson } else if ("gt".equals(entityName)) { 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ">"; 4060463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson } else if ("amp".equals(entityName)) { 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return "&"; 4080463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson } else if ("apos".equals(entityName)) { 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return "'"; 4100463b62eef5a7e8a477ddf7a972af198e46ecd5fJesse Wilson } else if ("quot".equals(entityName)) { 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return "\""; 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 416af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes 417af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes private String resolveCharacterReference(String value, int base) { 418af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes try { 419af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes int ch = Integer.parseInt(value, base); 420af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes if (ch < 0 || ch > Character.MAX_VALUE) { 421af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes return null; 422af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes } 423f787a8787d0b7bcdc178ffc2e3343f1c1b02ed30Elliott Hughes return String.valueOf((char) ch); 424af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes } catch (NumberFormatException ex) { 425af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes return null; 426af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes } 427af74d493c2c90d9394ec75be6a9d2b9f62cb5e5fElliott Hughes } 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 429