分享
 
 
 

[原创]JDOM and XML 解析, Part 2

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

[原创]JDOM and XML 解析, Part 2

用命名空间进行工作

JDOM为XML命名空间提供了丰富的,本地支持。在命名空间发布之后JDOM才被发布。在JDOM中,命名空间是通过Namespace类来描述的:

Namespace xhtml = Namespace.getNamespace(

"xhtml", "http://www.w3.org/1999/xhtml";);

通过构造,一个对象被赋予了一个名字并且能随意的给一个命名空间:

elt.addContent(new Element("table", xhtml));

如果没有给出的命名空间,被构造的元素将没有命名空间。一个元素的命名空间是它类型的本质的一部分,所以JDOM确保元素移动到文档的其它位置命名空间将不能被更改。如果一个元素没有命名空间并且移动到一个有命名空间的元素之下,它不继承命名空间。有时这将造成混淆,直到你学习了将textual描述从语义结构中分离。

XMLOutputter类挑选出命名空间,并且保证所有的”xmlns”声明在适当的位置。默认的,类的声明位置是必需的。如果你希望他们被进一步声明为树的形式,有可以用element.addNamespaceDecalaration()方法去提供一个指引。

所有JDOM元素和属性存取方法支持一个可选择的命名空间参数,这个参数指明了查看的是哪个命名空间。下面的例子指向了命名空间”xhtml”:

List kids = html.getChildren("title", xhtml);

Element kid = html.getChild("title", xhtml);

Attribute attr = kid.getAttribute("id", xhtml);

当调用存取方法的时候,仅仅和统一资源定位符(URLs)有关。这是因为XML Namespaces的工作方式。

如果没有为存取方法提供命名空间实例,那么将在没有命名空间的前提下搜索元素。JDOM用非常表面的描述方式去进行描述。没有命名空间意味着没有命名空间,没有上级命名空间或者可能产生新的bug。

关于ResultSetBuilder

ResultSetBuilder是对 JDOM的一个扩展,为了那些需要用XML文档去处理SQL结果集的那些人准备的。可以在org.jdom.conrib.input包里找到它。

ResultSetBuilder构造器接受一个java.sql.ResultSet作为输入参数,并且从它的build()方法返回一个org.jdom.Document。

Statement stmt = connection.createStatement();

ResultSet rs = stmt.executeQuery("select id, name from registry");

ResultSetBuilder builder = new ResultSetBuilder(rs);

Document doc = builder.build();

如果你不提供指定的配置信息,上面的代码构造的文档类似如下:

<result>

<entry>

<id>1</id>

<name>Alice</name>

</entry>

<entry>

<id>2</id>

<name>Bob</name>

</entry>

</result>

ResultSetBuilder类用查询的ResultSetMetaData类去决定列名,并且他们作为元素的名字。默认的,根元素有一个叫”result”的名字,并且每行有一个叫”entry”的名字。这些名字能够通过setRootName(String name)方法和setRowName(String name)方法进行更改。你也可以用setNamespace(Namespaces)方法为文档标识命名空间。

如果你希望要ResultSet列描述作为一个XML属性而不是一个元素,你可以调用setAsAttribute(String columnName)方法或者setAsAttribute(String columnName, String attributeName)方法—后面的方法改变属性的名字。你也可以用setAsElement(String columnName, String elemName)方法重命名。所有的这些方法都接受名字的索引。下面的代码片段用这些方法产生一个文档:

ResultSetBuilder builder = new ResultSetBuilder(rs);

builder.setAsAttribute("id");

builder.setAsElement("name", "fname");

Document doc = builder.build();

<result>

<entry id="1">

<fname>Alice</fname>

</entry>

<entry id="2">

<fname>Bob</fname>

</entry>

</result>

ResultSetBuilder类没有提供任何机制在数据库中存储XML文档。为了实现这个任务,你可以用一个本地XML书库,例如Oracle9i设置XML DB的性能。

内置XSLT

现在我们忽略核心库的基础东西,看一些高性能的处理,例如XSLT。

XSLT提供了将XML文档从一种格式转换为另一种格式的标准方法。用一个XML文件去处理变化,通常用已经存在的XML作为一个XHTML Web页面,或者将XML文档从一种模式转化为另一种模式。JDOM内置支持在内存中XSLT转化方式,用JAXP标准接口实现XSLT引擎。关键类是JDOMSource和JDOMResult,两种类都在org.jdo.transform包中。JDOMSource提供了一个JDOM文档作为转换的输入,JDOMResult捕获一个结果作为JDOM文档。Listing 1演示了一个基于内存转换的完整程序:

Code Listing 1: XSL Transform

import org.jdom.*;

import org.jdom.input.*;

import org.jdom.output.*;

import org.jdom.transform.*;

import javax.xml.transform.*;

import javax.xml.transform.stream.*;

public class XSLTransform {

public static void main(String[] args) throws Exception {

// Build the base document, just assume we get 2 params

String docname = args[0];

String sheetname = args[1];

SAXBuilder builder = new SAXBuilder();

Document doc = builder.build(docname);

// Use JAXP to get a transformer

Transformer transformer = TransformerFactory.newInstance()

.newTransformer(new StreamSource(sheetname));

// Run the transformation

JDOMSource source = new JDOMSource(doc);

JDOMResult result = new JDOMResult();

transformer.transform(source, result);

Document doc2 = result.getDocument();

// Display the results

XMLOutputter outp = new XMLOutputter();

outp.setTextNormalize(true);

outp.setIndent(" ");

outp.setNewlines(true);

outp.output(doc2, System.out);

}

}

你能够混合和匹配多种源和结果的实现。例如,如果你知道你仅仅打算输出一个文档并且不需要基于内存转换的JDOM描述,你可以用一个import javax.xml.transform.stram.StreamResult来替代它:

JDOMSource source = new JDOMSource(doc);

StreamResult result = new StreamResult(System.out);

transformer.transform(source, result);

XPath Included

XPath提供一个利用字符串搜索路径去查阅XML文档的机制。用XPath,你可以避免遍历文档,通过简单路径表达式仅仅解析你想要的信息。例如,让我们看下面的XHTML文档:

<table border="1">

<tr>

<th> </th>

<th>Open</th>

<th>Close</th>

</tr>

<tr>

<td>Sunday</td>

<td>11am</td>

<td>4pm</td>

</tr>

<tr>

<td>Monday</td>

<td>9am</td>

<td>5pm</td>

</tr>

</table>

在Beta8版本以后,JDOM提供了对XPath的内置支持,用org.jdom.xpath.XPath来完成。为了用XPath,你首先得利用XPath.newInstance()来构造一个XPath实例。

XPath xpath = XPath.newInstance("/some/xpath");

然后调用selectNodes()去获得基于给定上下文答案的一个列表。例如,这个上下文可以是一个文档或者是文档中的一个元素。

List results = xpath.selectNodes(doc);

有其他的方法去获得单个节点,数字值,字符串值等等。默认的XPath实现用Jaxen,可以参考http://jaxen.org

Listing2代码用XPath从web.xml文件中找出servlet部署描述的信息。给一个web.xml文件,Listing 3显示了一个web.xml文件:

Code Listing 2: XPath Pulls Information

import java.io.*;

import java.util.*;

import org.jdom.*;

import org.jdom.input.*;

import org.jdom.output.*;

import org.jdom.xpath.*;

public class XPathReader {

public static void main(String[] args) throws IOException, JDOMException {

if (args.length != 1) {

System.err.println("Usage: samples.XPathReader [web.xml]");

return;

}

String filename = args[0];

PrintStream out = System.out;

SAXBuilder builder = new SAXBuilder();

Document doc = builder.build(new File(filename));

// Print servlet information

XPath servletPath = XPath.newInstance("//servlet");

List servlets = servletPath.selectNodes(doc);

out.println("This WAR has "+ servlets.size() +" registered servlets:");

Iterator i = servlets.iterator();

while (i.hasNext()) {

Element servlet = (Element) i.next();

out.print("\t" + servlet.getChild("servlet-name")

.getTextTrim() +

" for " + servlet.getChild("servlet-class")

.getTextTrim());

List initParams = servlet.getChildren("init-param");

out.println(" (it has " + initParams.size() + " init params)");

}

// Print security role information

// Notice how we're directly fetching Text content

XPath rolePath = XPath.newInstance("//security-role/role-name/text()");

List roleNames = rolePath.selectNodes(doc);

if (roleNames.size() == 0) {

out.println("This WAR contains no roles");

}

else {

out.println("This WAR contains " + roleNames.size() + " roles:");

i = roleNames.iterator();

while (i.hasNext()) {

out.println("\t" + ((Text)i.next()).getTextTrim());

}

}

}

}

Code Listing 3: Example web.xml File (for use with XPath process in Listing 2)

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app>

<servlet>

<servlet-name>

snoop

</servlet-name>

<servlet-class>

SnoopServlet

</servlet-class>

</servlet>

<servlet>

<servlet-name>

file

</servlet-name>

<servlet-class>

ViewFile

</servlet-class>

<init-param>

<param-name>

initial

</param-name>

<param-value>

1000

</param-value>

<description>

The initial value for the counter <!-- optional -->

</description>

</init-param>

</servlet>

<distributed/>

<security-role>

<role-name>

manager

</role-name>

<role-name>

director

</role-name>

<role-name>

president

</role-name>

</security-role>

</web-app>

程序输出如下:

This WAR has 2 registered servlets:

snoop for SnoopServlet (it has 0 init params)

file for ViewFile (it has 1 init params)

This WAR contains 3 roles:

manager

director

president

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有