Board logo

标题: 几种操作 Feed 的 API 的示例及其比较 -1 DOM 以及 DOM API [打印本页]

作者: look_w    时间: 2018-8-23 20:22     标题: 几种操作 Feed 的 API 的示例及其比较 -1 DOM 以及 DOM API

DOM 以及 DOM API在开始使用 DOM 之前,对它究竟表示什么有个大概的了解是有所帮助的。DOM 是 Document Object Model,也就是所谓的文档对象模型。DOM 文档 是以层次结构组织的节点或信息片断的集合。开发人员可以在树中导航仪寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而 DOM 被认为是基于树或基于对象的。详细的 DOM 介绍请参考 w3 规范:Document Object Model (DOM) Level 2 HTML Specification 和文章:“。下面主要是以 DOM API 的使用为主介绍怎么使用 DOM API 从一个 XML 文档查询所需的信息。下面的代码示例是以 DOM Level2 的标准和实现为基础的。先来看代码清单 1:
清单 1. 用 DOM API 实现 Feed Query
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package xml.dom;

import java.io.InputStream;
import java.io.OutputStream;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DOMFilterFeed implements main.IFilterFeed{
   
public OutputStream filter(InputStream is, String xpathExpr){
  OutputStream os = System.out;
  try {
  // Create Dom Node Object from input Stream
  Node node = this.getDocument(is);
   
// Create XPath Object using same namespace context
  XPath xpathIns = this.createXPath();
   
// XPath expression
  String expression = "atom:feed/atom:entry[not(" + xpathExpr + ")]";
   
// Perform the XPath evaluation
  NodeList nodelist =
     (NodeList) xpathIns.evaluate(expression, node ,XPathConstants.NODESET);

  for (int i = 0; i <nodelist.getLength(); i++) {
  Node filteredNode = nodelist.item(i);
  filteredNode.getParentNode().removeChild(filteredNode);
  }
   
//serialize XML dom Node into outputStream
  this.serialize(os, node);
  
} catch (Exception e) {
  e.printStackTrace();
  }
  return os;
  }
   
private Node getDocument(InputStream is) throws Exception{
  Node node = null;
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  dbf.setNamespaceAware(true);
  dbf.setValidating(false);
  DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
  node = documentBuilder.parse(is);
  return node;
  }
   
private XPath createXPath(){
  XPathFactory factory = XPathFactory.newInstance();
  XPath xpath = factory.newXPath();
  NamespaceContext nsctx = new SampleNamespaceContext();
  if (nsctx == null) {
  nsctx = new SampleNamespaceContext();
  }
  xpath.setNamespaceContext(nsctx);
  return xpath;
  }
   
private void serialize (OutputStream outputStream, Node node) {
try {
  final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance();
   Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
   
   DOMSource source = new DOMSource(node);
  StreamResult sResult = new StreamResult(outputStream);
   
  transformer.transform(source, sResult);
   
} catch (TransformerException te) {
  throw new RuntimeException(te);
  }
  }
}




其中 main.IFilterFeed 是程序自定义的一个借口。定义了 filter 接口。详细的 code 可以从所附的源代码里面获得。
从上面的代码示例清单 1 可以看出,DOM API 的使用还是比较繁琐的,要实现在一个 feed 里面查找满足条件(XPath Expression 表示)的一些信息,需要很多步骤:
在这一步,程序需要创建 DocumentBuilderFactory 的实例,然后需要设置一些属性比如设置 DocumentBuilder 是不是 namespace aware 的,以及是否需要按照 XML 规范对输入的 XML 做一些格式的校验。然后由 DocumentBuilderFactory 创建 DocumentBuilder,继而在调用 DocumentBuilder 的 parse 方法创建 DOM Node.
用 XPathFactory 创建 XPath 对象,并把 namespace 设置成第二步里面创建的 SampleNamespaceContext。
把生成的 DOM Node 序列化到 output stream 或者 writer。本示例使用了 XSLT 作为了完全转换,输入到 output stream。
另一方面,DOM 还提供了一系列 API,允许开发人员添加、编辑、移动或删除树中任意位置的节点,从而创建一个应用程序。
因为 DOM 是基于层次树的操作,所以在执行任何操作前,程序都需要把整个文档加载到内存,并在内存中创建一颗 DOM 树。这对于特别大的文档,解析和加载整个文档可能很慢且很耗资源。但是程序员可以在 DOM 树上任意行走,任意增删改 DOM Node,这也许是 DOM 的一个很大的好处。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0