使用 IBM XML 语法分析器 (XML4J) 查找和替换 XML 文档中的元素
LindaMay Patterson
IBM 软件工程师
2000 年 7 月
内容:
基础
XML 语法分析器
语法分析
结束语
参考资料
关于作者
XML4J 语法分析器一种以结构化形式再现 XML 文档以便操纵每个元素的工具。本文将介绍一个样本 XML 文档及其文档类型定义 (DTD),并通过使用 XML4J 语法分析器来描述如何访问 XML 文档所包含的信息。
Extensible Markup Language(可扩展标记语言),简称 XML,开启了以各种方法共享商业信息的大门。一些使用 XML 的主要原因包括:
弥补 HTML 的不足(XML 提供自描述数据)
在商家到商家事务方面,类似于现今的 EDI 用法
作为不同种应用程序之间的公共通信工具
HTML 在为 Web 提供信息方面非常成功,然而,HTML 有一些缺陷。因为 XML 文档是自描述的,所以 XML 能提供额外的灵活性。对 Web 内容使用 XML 的一个有趣特性是在搜索领域方面:搜索引擎可以使用标记和数据作为搜索条件的一部分,这样就可以更精确地匹配 Web 内容。可以使用可扩展样式表语言 (XSL) 样式表来格式化文档,从而可以在支持 XML 的浏览器中查看 XML 文档。
在商家到商家事务中使用 XML,以及将 XML 用作不同种应用程序之间的公共通信工具都要求有一种机制可以读取 XML 文档并将其解释成便于计算机处理的形式。应用程序需要一种访问每一个 XML 文档所包含的个别信息(元素)的方式。这是使用 XML 语法分析器以结构化形式(分层树状结构)再现文档来实现的,从而允许访问和操纵文档中的每一个元素。 基础
每个 XML 文档都由特定于该文档的元素组成。图 1 显示了 XML 元素的结构。带有内容的元素具有开始和结束标记,并在标记之间包含内容。不带内容的元素通常用于组织文档结构,它可以有一个在大于号 (>) 之前具有斜杠 (/) 的开始标记,表示没有内容。可以将元素组织成十分类似于现今的文件这样的结构;其嵌套层次可由开始和结束标记的位置反映出来。 图 1:XML 元素的结构
任何元素都可以拥有属性,这些属性进一步定义元素。如图 2 所示,在元素的开始标记中定义属性。 图 2:具有属性的 XML 元素
每个属性都由名称和值组成。必须用双引号 (") 将值括起。每个元素可以有任意多的属性,这取决于设计者的需要。每个设计者都必须确定要将相关信息表示成子元素还是属性 -- 这方面没有严格规定。
图 3 显示了本文中使用的文档。该文档包含商品目录数据。已经将该文档缩排以显示文档的层次结构。 图 3 - 表示电子目录的 XML 文档
此 XML 文档包含两种羊毛衫信息,男式和女式。每种商品(羊毛衫)的信息都位于一对标记中。请注意 shippingcost 标记没有结束标记,而是在开始标记中的 shippingcost 之前有一个斜杠 (/)。这就是没有内容的空标记。它可以充当占位符留作以后使用。
XML 文档应该有文档类型定义 (DTD) 以验证 XML 正确与否。DTD 包含 XML 文档的结构、所有关于元素间关系的规则和特定于某一元素的规则。DTD 表示结构中元素的层次结构和嵌套。
图 4 显示了定义 catalog 文档结构的 DTD。这个 DTD 包含各种嵌套的、以 catalog 作为根项的嵌套结构。在解释该 DTD 之前,需要理解以下基本原则:
if (document != null) { // Print the initial state of the document starting at the root element System.out.println("******************BEFORE*******************"); printElement(document.getDocumentElement()); // Perform a find replace on the document document = findReplace(document, targetElement, valueToFind, valueToReplace); // Print the resulting state of the document starting at the root element System.out.println("*******************AFTER*******************"); printElement(document.getDocumentElement()); } else{ System.out.println(" in main document null"); }}
private static void printElement(Element element) { int k; NamedNodeMap attributes; NodeList children = element.getChildNodes(); //***** Start this element System.out.print("<" + element.getNodeName()); //***** Get any attibutes and print them inside the element start tag attributes = element.getAttributes(); if (attributes != null) { for (k = 0; k < attributes.getLength(); k++) { System.out.print(" " + attributes.item(k).getNodeName()); System.out.print("=" + attributes.item(k).getNodeValue()); } } if (element.hasChildNodes()) { //***** If this element has a value or sub-elements System.out.print(">"); //** For each child, if the child is an element call print element to print that //** portion of the tree, if it is a text node, print the text to stdout. //** All other node types are ignored for the sake of simplicity. for (k = 0; k< children.getLength(); k++) { if (children.item(k).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { printElement((Element) children.item(k)); } else if (children.item(k).getNodeType() == org.w3c.dom.Node.TEXT_NODE) { System.out.print(children.item(k).getNodeValue()); } } // end for loop //***** Add a closing tag System.out.print(""); }// end else }// end method
static private Document findReplace(Document document, String elementName, String valueToFind, String valueToReplace) { int i; int k; NodeList children; Element docRoot = document.getDocumentElement(); //*** Get the root element NodeList elements = docRoot.getElementsByTagName(elementName); if (elements != null) { //** For each element matching the search element for (i = 0; i<elements.getLength(); i++) { if (elements.item(i).hasChildNodes()) { children = elements.item(i).getChildNodes(); for (k = 0; k
类中唯一没有讨论的方法是 usage() 方法,在处理过程中发生错误时将调用该方法。该方法包括一个 println,它将打印在调用该类时传递的值。 结束语
本文提供了一个使用 XML 语法分析器 (XML4J) 的示例,以及由该语法分析器和 DOM API 所提供的各种访问与更新 XML 文档的功能。下载该语法分析器时,您将发现其中的文档包括了有关 XML4J 和与之相关的类和方法的详细信息。
参考资料
从 alphaWorks 下载 XML4J 语法分析器。
了解 AS/400 Toolbox for Java。
关于作者
LindaMay Patterson 是 IBM Rochester AS/400 部门的 PartnerWorld for Developers 顾问程序员。她已经在 IBM 工作了 24 年,从事过各种商业应用环境。目前,她是 PartnerWorld for Developers 的成员之一,这是个使用 Enterprise JavaBean 技术的 AS/400 Java 技术小组。在这之前,她一直从事 SanFrancisco 产品方面的工作,负责开发教育软件包并在德国从事帮助定义产品内容的工作。她的应用开发背景主要在分发和后勤系统方面。可以通过 lindamay@us.ibm.com 与 LindaMay 联系。