分享
 
 
 

JDOM Programming Part 2

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

JDOM and XML Parsing, Part 2

By Jason Hunter

JDOM makes XML manipulation in Java easier than ever.

In the first article of this series, I introduced JDOM, an open-source library for Java-optimized XML data manipulations. I explained how this alternative document object model was not built on DOM or modeled after DOM but was created to be Java-specific and thereby take advantage of Java's features, including method overloading, collections, reflection, and familiar programming idioms. I covered the important classes and started examining how to use JDOM in your applications. In this article, I'll take a look at XML Namespaces, ResultSetBuilder, XSLT, and XPath.

Working with Namespaces

JDOM provides robust, native support for XML Namespaces. JDOM was created after the namespace recommendation was published, so unlike other APIs there's no pre-namespace and deprecated leftovers. (See the sidebar "XML Namespaces" for more on namespaces.) In JDOM, namespaces are represented by a Namespace class:

Namespace xhtml = Namespace.getNamespace(

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

During construction, an object is given a name and can optionally be given a namespace:

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

If no namespace is given, the element is constructed in "no namespace." An element's namespace is an intrinsic part of its type, so JDOM ensures that its namespace doesn't change when it moves around the document. If an element has no namespace and moves under an element that has a namespace, it explicitly does not inherit the namespace. Sometimes that causes confusion until you learn to separate the textual representation from the semantic structure.

The XMLOutputter class sorts out the namespace issues and ensures placement of all the "xmlns" declarations into the appropriate locations, even after a document's elements have been heavily shuffled around. By default, the class places the declarations where they're first necessary. If you want them declared further up the tree (in other words, all declarations at the root), you can use the element.addNamespaceDeclaration() method to provide that guidance.

All JDOM element or attribute accessor methods support an optional namespace argument indicating the namespace in which to look. This example points to the xhtml namespace:

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

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

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

When calling accessor methods, it's only the uniform resource identifiers (URIs) that matter. That's because of how XML Namespaces work.

If no namespace instance is provided to the accessor methods, the search looks for elements without a namespace. JDOM uses a very literal representation. No namespace means no namespace, not "the parent's namespace" or anything that might cause later bugs.

More About ResultSetBuilder

ResultSetBuilder is an extension to JDOM created for people who need to treat a SQL result as an XML document. Look for it in the jdom-contrib repository in the org.jdom.contrib.input package.

The ResultSetBuilder constructor accepts a java.sql .ResultSet as input and returns an org.jdom.Document from its build() method.

Statement stmt = connection.createStatement();

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

ResultSetBuilder builder = new ResultSetBuilder(rs);

Document doc = builder.build();

If you don't provide any special configuration information, the above code constructs a document similar to the following:

<result>

<entry>

<id>1</id>

<name>Alice</name>

</entry>

<entry>

<id>2</id>

<name>Bob</name>

</entry>

</result>

The ResultSetBuilder class uses the query's ResultSetMetaData to determine the column names and uses them as the element names. By default, the root element has the name "result," and each row has the name "entry." These names can be changed with setRootName(Stringname) and setRowName(Stringname). You can also assign a namespace for the document with setNamespace(Namespaces).

If you want a ResultSet column represented as an XML attribute instead of an element, you can call setAsAttribute(StringcolumnName) or setAsAttribute (StringcolumnName, StringattribName)—the latter method changes the name of the attribute. You can also rename elements using setAsElement(StringcolumnName, StringelemName). Both of these calls accept numbered indexes instead of names, if you prefer. The following code snippet uses these calls to reformat the generated document:

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>

The class doesn't provide any mechanism to store XML documents in a database for later retrieval or to make XQuery calls against data in the database. To accomplish these tasks, you would need a native XML database, such as Oracle9i's feature set, XML DB.

Built-in XSLT

Now that we've covered the basics of the core library, let's look at some higher-level features, such as eXtensible Stylesheet Language Transformation (XSLT) language.

XSLT provides a standard way to convert XML content from one format into another, using an XML file to handle the conversion. It's commonly used in presenting XML as an XHTML Web page, or in changing XML between one schema and another. JDOM provides built-in support for in-memory XSLT transformations, using the JAXP standard interface to XSLT engines. The key classes are JDOMSource and JDOMResult in the org.jdom.transform package. JDOMSource provides a JDOM document as input to the translation; JDOMResult catches the results as a JDOM document. Listing 1 demonstrates a complete program that performs an in-memory transformation.

You can mix and match various source and result implementations. For example, if you know you're only going to output the document and don't need the in-memory JDOM representation, you could use an import javax.xml.transform .stream.StreamResult instead:

JDOMSource source = new JDOMSource(doc);

StreamResult result = new StreamResult(System.out);

transformer.transform(source, result);

The downside is that you lose out on the nice XMLOutputter pretty formatting.

XPath Included

XPath provides a mechanism to refer to parts of an XML document using a string lookup path. Using Xpath, you can avoid walking a document and extract just the information you want based on simple path expressions. For example, let's look at the following XHTML document:

<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>

You can select the Open time for Monday as /table/tr[td= "Monday"]/td[2]. In code releases after Beta 8, JDOM provides built-in support for XPath using the org.jdom.xpath.XPath class. To use it, you first construct an XPath instance by calling XPath.newInstance() with an expression to compile:

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

Then you call selectNodes() to get a list of answers based at a given context. The context can, for example, be the document or an element within the document.

List results = xpath.selectNodes(doc);

There are other methods for retrieving single nodes, number values, string values, and such. The default XPath implementation uses Jaxen from http://jaxen.org.

The code in Listing 2 uses XPath to pull information from a servlet deployment descriptor web.xml file. Given a web.xml file, as shown in Listing 3, the output looks like this:

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

New Features of JDOM Beta 9

JDOM is at Beta 8, with the next beta release producing a near-final API. Some API changes for the Beta 9 release are:

Expose a mechanism to easily iterate over the entire document tree.

Expose the Filter interface currently used internally so a programmer can walk only the parts of the tree that satisfy a given programmatic filter rule.

Include a base interface to aid in these traversal models, to allow for detaching content without knowing its exact type.

Provide a class to simplify XSLT transformations and hide the JAXP calls.

Finalize a mechanism to handle outputting of characters not actually available in the programmer-selected output charset.

JDOM allows Java programmers to easily and effectively interact with XML. It was created to be easy to learn, powerful, and natural for Java programmers. It's released under open source with a commercial-friendly license, so it's free to use; it integrates well with JAXP, DOM, and SAX; and it is an official JSR overseen by the Java Community Process.

Jason Hunter is publisher of Servlets.com and vice president of the Apache Software Foundation, and he holds a seat on the JCP Executive Committee.

XML NAMESPACES Namespaces can be a tricky business in XML. The goal of namespaces is similar to that of Java packages, where two classes with the same name can be differentiated by their package. Yet few people really understand what the following means: <xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"> <xhtml:title>Home Page</xhtml:title></xhtml:html>Here's the short summary. In the <html> element, the "xmlns:xhtml=" attribute name is special. It's a namespace declara-tion. It indicates that "xhtml" (or whatever comes after "xmlns:") should be an alias for the URI that appears in the attribute's value. Specifically, it means that for that element and any content under the declaring element, the "xhtml" prefix on a name means the item is in the "http://www.w3.org/1999/xhtml" namespace. That namespace looks like a Web address, but it's not. It's just a string. And it's important to note that "xhtml" is an alias and not the namespace itself. There's a special namespace called the default namespace. It's the namespace without a prefix. By using a default namespace, the earlier xhtml content could be written yet another way: <html xmlns="http://www.w3.org/1999/xhtml"> <title>Home Page</title></html>If the "xmlns=" declaration did not exist in this XML, the elements would reside in "no namespace." In many ways, it's like the default package in Java.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有