DOM解析XML(二)
来源:互联网 发布:工商银行网络银行 编辑:程序博客网 时间:2024/05/16 04:58
我们还是把上一篇中的实例放上来接着分析
import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.hibernate.util.ConfigHelper;import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.w3c.dom.Node; public class DomParseService { public static List<Book> getBooks(InputStream inputStream) throws Exception{ List<Book> list = new ArrayList<Book>(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); //传入参数inputstream,解析指定的xml,解析完成之后会返回一个Document(这里我们可以理解成一棵树) Document document = builder.parse(inputStream); //或者这棵树上的元素(种类很多) Element element = document.getDocumentElement(); NodeList bookNodes = element.getElementsByTagName("book"); for(int i=0;i<bookNodes.getLength();i++){ Element bookElement = (Element) bookNodes.item(i); Book book = new Book(); book.setId(Integer.parseInt(bookElement.getAttribute("id"))); NodeList childNodes = bookElement.getChildNodes(); // System.out.println("*****"+childNodes.getLength()); for(int j=0;j<childNodes.getLength();j++){ if(childNodes.item(j).getNodeType()==Node.ELEMENT_NODE){ if("name".equals(childNodes.item(j).getNodeName())){ book.setName(childNodes.item(j).getFirstChild().getNodeValue()); System.out.println("nodeValue = " + childNodes.item(j).getFirstChild().getNodeValue()); }else if("price".equals(childNodes.item(j).getNodeName())){ book.setPrice(Float.parseFloat(childNodes.item(j).getFirstChild().getNodeValue())); System.out.println("nodeValue = " + Float.parseFloat(childNodes.item(j).getFirstChild().getNodeValue())); } } }//end for j list.add(book); }//end for i return list; } public static void main(String[] args) { InputStream inputStream = ConfigHelper.getResourceAsStream("/book.xml"); try {getBooks(inputStream);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
上一篇中我们知道了,DocumentBuilderFactory.newInstance()最终返回的是DocumentBuilderFactoryImpl,那我们接着往下看newDocumentBuilder()方法:
/** * Creates a new instance of a {@link javax.xml.parsers.DocumentBuilder} * using the currently configured parameters. */ public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { /** Check that if a Schema has been specified that neither of the schema properties have been set. */ if (grammar != null && attributes != null) { if (attributes.containsKey(JAXPConstants.JAXP_SCHEMA_LANGUAGE)) { throw new ParserConfigurationException( SAXMessageFormatter.formatMessage(null, "schema-already-specified", new Object[] {JAXPConstants.JAXP_SCHEMA_LANGUAGE})); } else if (attributes.containsKey(JAXPConstants.JAXP_SCHEMA_SOURCE)) { throw new ParserConfigurationException( SAXMessageFormatter.formatMessage(null, "schema-already-specified", new Object[] {JAXPConstants.JAXP_SCHEMA_SOURCE})); } } try { return new DocumentBuilderImpl(this, attributes, features, fSecureProcess); } catch (SAXException se) { // Handles both SAXNotSupportedException, SAXNotRecognizedException throw new ParserConfigurationException(se.getMessage()); } }
这里我们看到最终返回的实例是DocumentBuilder的实现类DocumentBuilderImpl,所以要注意这个类中对父类的实现方法
/** * Parse the content of the given <code>InputStream</code> as an XML * document and return a new DOM {@link Document} object. * An <code>IllegalArgumentException</code> is thrown if the * <code>InputStream</code> is null. * * @param is InputStream containing the content to be parsed. * * @return <code>Document</code> result of parsing the * <code>InputStream</code> * * @throws IOException If any IO errors occur. * @throws SAXException If any parse errors occur. * @throws IllegalArgumentException When <code>is</code> is <code>null</code> * * @see org.xml.sax.DocumentHandler */ public Document parse(InputStream is) throws SAXException, IOException { if (is == null) { throw new IllegalArgumentException("InputStream cannot be null"); } InputSource in = new InputSource(is); return parse(in); }
/** * Parse the content of the given input source as an XML document * and return a new DOM {@link Document} object. * An <code>IllegalArgumentException</code> is thrown if the * <code>InputSource</code> is <code>null</code> null. * * @param is InputSource containing the content to be parsed. * * @return A new DOM Document object. * * @throws IOException If any IO errors occur. * @throws SAXException If any parse errors occur. * @throws IllegalArgumentException When <code>is</code> is <code>null</code> * * @see org.xml.sax.DocumentHandler */ public abstract Document parse(InputSource is) throws SAXException, IOException;
public Document parse(InputSource is) throws SAXException, IOException { if (is == null) { throw new IllegalArgumentException( DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "jaxp-null-input-source", null)); } if (fSchemaValidator != null) { if (fSchemaValidationManager != null) { fSchemaValidationManager.reset(); } resetSchemaValidator(); } domParser.parse(is); return domParser.getDocument(); }
这里domParser.parse(is)调用的是XMLParser类中的方法:
/** * parse * * @param inputSource * * @exception XNIException * @exception java.io.IOException */ public void parse(XMLInputSource inputSource) throws XNIException, IOException { reset(); fConfiguration.parse(inputSource); } // parse(XMLInputSource)
这里fConfiguration.parse(inputSource)方法是调用的com.sun.org.apache.xerces.internal.parsers.XML11Configuration类中的parse(XMLInputSource source)方法,为什么会调用到这里来呢,因为在实例化DOMParser对象的时候:
/** * Constructs a DOM parser using the specified symbol table and * grammar pool. */ public DOMParser(SymbolTable symbolTable, XMLGrammarPool grammarPool) { super((XMLParserConfiguration)ObjectFactory.createObject( "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", "com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration" )); // set properties fConfiguration.addRecognizedProperties(RECOGNIZED_PROPERTIES); if (symbolTable != null) { fConfiguration.setProperty(SYMBOL_TABLE, symbolTable); } if (grammarPool != null) { fConfiguration.setProperty(XMLGRAMMAR_POOL, grammarPool); } fConfiguration.addRecognizedFeatures(RECOGNIZED_FEATURES); } // <init>(SymbolTable,XMLGrammarPool)
因为XIncludeAwareParserConfiguration类的父类为XML11Configuration类,所以就显得清晰明了:
/** * Parses the specified input source. * * @param source The input source. * * @exception XNIException Throws exception on XNI error. * @exception java.io.IOException Throws exception on i/o error. */ public void parse(XMLInputSource source) throws XNIException, IOException { if (fParseInProgress) { // REVISIT - need to add new error message throw new XNIException("FWK005 parse may not be called while parsing."); } fParseInProgress = true; try { setInputSource(source); parse(true); } catch (XNIException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; } catch (IOException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; } catch (RuntimeException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; } catch (Exception ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw new XNIException(ex); } finally { fParseInProgress = false; // close all streams opened by xerces this.cleanup(); } } // parse(InputSource)
这里面具体怎么实现的,我在再下一章好好研究一下。
总结:在查看源码的时候,我总是会出现找不到源码的情况,除了与jdk中版本不一致之外,还有个根本的原因就是java基础知识太差了,像什么子类可以直接使用父类的方法,子类重写父类的方法之后,程序会用到子类的方法等等这些基础的知识点,以前在学习或者面试的时候感觉那个时候都是背的,时间长了之后天天写CRUD,一致与现在都搞不清楚这些最基本也是最重要的知识点了,现在越来越觉得坚持看源码,虽然过程很痛苦,但是日积月累之后我的代码功力肯定会大大提高,加油。
0 0
- XML解析(二),DOM解析XML
- DOM解析XML(二)
- XML解析:二、Dom解析
- Java解析XML(二)、DOM
- XML解析二 使用DOM解析XML
- 浅谈XML 解析技术(二) Dom 解析
- XML(DOM)解析
- Android 创建与解析XML(二)---- DOM方式
- 存储方式二:文件(XML DOM解析)
- android之dom解析xml 样式二
- Android下Xml解析技术(二)、DOM解析Xml文件
- Android下Xml解析技术(二)、DOM解析Xml文件
- dom解析xml(转)
- DOM解析XML(转)
- xml解析(dom java)
- DOM解析XML(一)
- DOM解析XML(三)
- DOM解析XML(四)
- swift写的第一个helloWorld 变量和常量相对oc的区别
- Unity3D如何接入第三方的SDK - Android篇
- copy_to_user和copy_from_user两个函数的分析
- Utilities之auto_ptr
- 【转】DataGridView 的重绘
- DOM解析XML(二)
- try catch多个catch捕获问题
- hdu2065--红色病毒
- Unlities之numeric_limits
- c++ double类型的误差
- [iOS Crash文件分析]-如何使用symbolicatecrash工具
- 烤鸭的gerrit使用总结
- 单元测试之覆盖率浅谈
- 怎么查询局域网内全部电脑IP和mac地址等信息?