新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 关于 XML 的一般性技术讨论,提供 XML入门资料 和 XML教程
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - XML技术『 XML基础 』 → (转)使用 XJ 简化 XML 处理 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 12672 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: (转)使用 XJ 简化 XML 处理 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     菜籽 帅哥哟,离线,有人找我吗?双鱼座1981-2-28
      
      
      威望:5
      头衔:软件民工
      等级:研二(Sowa的知识表示写得真好!)
      文章:875
      积分:5655
      门派:XML.ORG.CN
      注册:2004/7/25

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给菜籽发送一个短消息 把菜籽加入好友 查看菜籽的个人资料 搜索菜籽在『 XML基础 』的所有贴子 点击这里发送电邮给菜籽 引用回复这个贴子 回复这个贴子 查看菜籽的博客楼主
    发贴心情 (转)使用 XJ 简化 XML 处理

    集成 XML 和 Java 技术
    级别: 初级

    Rajesh Bordawekar, 研究组成员, IBM Research
    Michael G. Burke, 研究组成员, IBM Research
    Igor Peshansky, 研究组成员, IBM Research
    Mukund Raghavachari, 研究组成员, IBM Research

    2005 年 7 月 18 日

    使用 XML、XPath 和 XML Schema 的一流支持扩展 Java™ 技术,从而使 XML 处理应用程序更容易编写、更健壮和更高效。本文全面介绍 XML Enhancements for Java™ (XJ),这是一组在 Java 编程语言中对 XML 添加直接支持的语言扩展。本文的作者们就是开发 XJ 的小组成员。
    何为 XJ?
    许多现有机制可以在 Java 代码中处理 XML,包括诸如 DOM 和 SAX 之类的运行时 API,以及诸如 JAXB 之类的数据绑定方法。在所有这些方法中,XML 支持被嫁接到 Java 编程语言中 —— 编绎器无法知道程序的哪一部分处理 XML 数据。其结果是,XML 处理应用程序的健壮性和效率均不如人意。

    在 XML Enhancements for Java (XJ) 项目中(初始发行版可在 IBM alphaWorks 中获得),我们采用了另一种方法。XJ 将 XML 作为一流的构造集成到 Java 技术中。程序员可以导入 W3C XML Schema 中的声明,仿佛它们就是一些 Java 类。他们能够编写内联 XPath 表达式以导航 XML 数据,而且能够通过编写内联 XML 来构造 XML 数据(如果您熟悉 ECMAScript for XML,XJ 的构造情况与此技术相似;关于 E4X 的详细信息,请参阅 参考资料)。由于 XML 的有关知识已嵌入 Java 语言,所以编绎器能够检验 XML 处理应用程序关于 XML Schema 声明部分是否正确,并执行优化以使应用程序运行效率更高。与诸如 XSLT 之类的基于 XML 的语言相比,XJ 的优势在于其中的 XML 处理应用程序将全部的 Java 技术,包括现有的全部库,都纳入它们的掌握之中。许多转换用 XJ 编写比用 XSLT 编写更加容易。

    XJ 是 Java 1.4 的严格扩展。任何有效的 Java 1.4 程序都是有效的 XJ 程序。该发行版包括两个可执行文件:一个从 XJ 源代码生成类文件的 xjc 编绎器和一个用于运行 XJ 程序的 xj 运行时环境。xjc 是一个扩展的 javac 编绎器,它理解 XML Schema、XPath 表达式和 XML。由 xjc 产生的类文件是标准 Java 类文件,可以在任何 Java 虚拟机上运行。xj 运行时环境是一个围绕 java 的瘦包装器,它在调用 java 之前将 XJ 运行库添加到类路径下。

    在本文中,我们将通过一个例子来了解将 XML 支持集成到 Java 语言是如何简化 XML 开发人员的工作的。 XJ 的优势可以概括为:

    熟悉(对于 XML 程序员): XJ 中的 XML 处理与开放式 XML 标准相一致。
    健壮性: XJ 程序与 XML Schemas 是强类型匹配的。XJ 编绎器能够检测使用 XPath 表达式和构造 XML 数据中的错误。
    易维护性: 由于 XJ 程序是按照 XML 编写的,它不是诸如 DOM 或 SAX 之类的低级 API,如果 XML Schemas 发生改变,它们很容易维护和修改。
    性能: 由于编绎器能够觉察在程序中使用了 XML,所以它能够优化 XML 的运行时表示、解析和 Path 计算。
    细论 XJ
    既然我们已经了解了 XJ 幕后的设计原则,就让我们来看一下它的细节吧。 我们将用一些例子来演示添加到该语言的三种新构造:

    XML Schema 声明,可用作 Java 类型。
    XML 数据,可通过编写 XML 内联来构造。
    XPath 表达式,可编写它以导航 XML 数据。
    关于 XML Schema 声明
    想像一下如果是在 Java 中,您不能指定类名作为变量或参数的类型;您惟一可以声明的类型是 Object。如果您编写一个方法,它需要一个实例,比如 Sales 类的实例作为参数,您将不得不将输入参数指定为 Object 类型。编绎器无法验证只有 Sales 对象被传递给该方法,因此各种不可预测的错误都可能在运行时发生。编程将变得十分困难,代码也将更难维护,而且您不得不为每个方法添加注释,以回忆起允许输入哪些类。

    在本质上,这恰似 XML 编程呈现给 Java 程序员的世界。例如,在使用 DOM 编程时,您只能指定方法的输入是一个 Element,而无法告诉编绎器该方法只能接受相应于某个给定的模式(schema)中的 sales 元素是有效的 XML。如果代码给方法传递错误的元素,那么尽管代码将编绎良好,但可能会导致运行时错误或者不返回任何结果。XJ 允许程序员指定程序中处理的 XML 元素的类型,从而提高程序的健壮性和可维护性。编绎器按照 XML Schema 的约束进行检验,以确保 XML 数据的使用正确。

    为了帮助您更好地理解 XJ 是如何将 XML Schema 集成到 Java 技术中的,我们将回顾 Java 语言是如何允许程序员指定类型名称的。考虑语句 import com.ibm.xj.samples.totals.salesschema.*。Java 编绎器试图在类路径中发现一个与 salesschema 相对应的包或类型,并允许导入其中声明的所有可访问类型。如果编绎器未能发现与 salesschema 相应的包或类型,它就会产生一个错误。在 XJ 中,如果编绎器未能找到相应一个名称的包或类型,则它试图寻找一个相应的 XML Schema 文件。因此,在本例中,它试图使用类路径寻找一个称为 com/ibm/xj/samples/totals/salesschema.xsd 的模式。如果这样的模式已经存在,则编绎器导入该 XML Schema 中所有的全局元素声明。在此意义上,一个 XML Schema 对应一个包,全局元素声明对应包中的顶级类,而局部元素声明对应顶级类中的嵌套类。现在让我们看一个名为 salesschema.xsd 的程序段:

    清单 1. XML Schema 示例

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:element name="salesdata">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="year" type="YearType"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
       ....
    <xsd:schema>

    语句 import com.ibm.xj.samples.totals.salesschema.* 表示,任何对 salesdata 的引用都引用上述模式中的全局元素声明。类似地,XJ 类型 com.ibm.xj.samples.totals.salesschema.salesdata.year 引用 salesdata 中 year 的局部声明。这就是说,开发人员可以自由地声明这些类型的变量和参数。编绎器将确保所有这些派生自 XML Schema 的类型的使用(用在 XPath 表达式中、XML 数据的构造中以及方法调用中)都是正确的。

    XML 的构造
    使用诸如 DOM 之类的运行时库,XML 的构造工作将是一个充满痛苦的过程。程序员必须逐步地构建一棵树,构造每个节点并将其插入到该树中的某个位置。在构造元素和属性时,程序员将字符串传递给运行时库。只有当构造的文档有效时才能在运行时捕获拼写或其他错误。相反,XJ 允许程序员通过编写内联 XML 来构造 XML 数据。程序员能够剪切-粘贴他们想要生成的 XML 并将它们包括到程序中。编绎器根据声明的类型检验构造的 XML 是否有效(而且也可以优化构造)。例如,假设您想要创建下面的 XML 程序段:

    清单 2. XML 程序段

    <region>
      <name>central</name>
      <sales unit="millions">12</sales>
    </region>

    使用 DOM,您必须构建该树(参见清单 3)。注意,所有传递到 DOW API 的元素标签名称都是字符串。这不仅容易出错,而且代码很难译解。

    清单 3. XML 程序段的 DOW 构造

    Element region = doc.createElement("region");
    Element name = doc.createElement("name");
    Text text = doc.createTextNode("central");
    name.appendChild(text);
    region.appendChild(name);
    Element sales = doc.createElement("sales");
    text = doc.createTextNode("12");
    sales.appendChild(text);
    sales.setAttribute("unit", "millions");
    region.appendChild(sales);

    另一方面,比较清单 3 与清单 4 中的 XJ 代码,后者直接来自原始的 XML:

    清单 4. XML 程序段的 XJ 构造

    region r = new region(
    <region>
      <name>central</name>
      <sales unit="millions">12</sales>
    </region>);

    XJ 允许轻松构造动态的 XML。例如,考虑清单 5,其中 sales 的值是动态计算的。字面量 XML 中的括号“{”和“}”用于定界表达式,该表达式在运行时进行计算以构造该 XML。

    清单 5. XML 程序段的动态 XJ 构造

    int million = 1000000;
    int sales = 12000000;
    region r = new region(
    <region>
      <name>central</name>
      <sales unit="millions">{ sales / million} </sales>
    </region>);

    除了根据字面量 XML 来构造之外,XJ 还通过在每个 XJ XML 类上提供一个 java.io.InputStream 构造函数来读取外部源中的 XML 数据。例如,new region(is) 将把 is 中存储的数据装载到内存中(其中 is 是 InputStream 类型的一个变量)。

    XPath 表达式
    XPath 是一种强大的语言,它允许您编写用来从 XML 数据中检索信息的简明表达式。运行时 API,诸如 DOM,正在倾向于允许程序员编写 XPath 表达式而不是编写明确的树遍历代码(后者是一个痛苦的过程)。然而,运行时方法具有两个缺点。首先,XPath 以字符串的形式传递到运行时库。XPath 中的简单错误,比如语法错误,直到运行时才能被捕获。运行时 API 无法检测到其他错误,比如错误拼写了文档中的一个元素的名称:XPath 计算将不返回结果。运行时 API 的第二个问题是性能。运行时库必须在运行时解析并计算 XPath 表达式。运行时库没有机会分析程序并以最优的方式构建查询计算。

    XJ 通过将 XPath 表达式的知识引入该语言来解决这些问题。编绎器将根据元素的 XML Schema 类型来验证该元素上的 XPath 计算是适当的(在编绎时检测很多错误)。而且,即将出现的版本(不久就会发布)将能够生成计算 XPath 表达式的最优化代码。

    例如,如果您想要在一个文档中找出所有满足某个属性的 region 元素,即该属性中包含的 sales 要大于某个用户提供的变量,那么您可以使用 XJ 编写下列代码:

    清单 6. XPath 表达式示例

    salesdata sd = ...;
    int min = ...;
    Sequence<region> regions = sd [| //region[sales > $min] |];
    for (XMLCursor<region> i = regions.iterator(); i.hasMoreElements(); ) {
       region r = i.next();
       String s = r[| /name |];
       System.out.println("Region: " + s);
    }

    在清单 6 中,XPath 表达式 sd [| //region[sales > $min] |] 按下列步骤来计算:表达式 sd 指定 XPath 表达式要对其进行计算的一个或多个 XML 元素(也就是上下文节点)。定界符“[|”和“|]”指定对上下文节点进行计算的 XPath 表达式。注意到,它能够引用词法作用域中的任何变量(本例中是 min)。编绎器根据指定的模式确保 XPath 表达式正确。在本例中,它确保 salesdata 元素具有 region 子元素,这些子元素又具有 sales 子元素,后者的内容可以同一个 int 类型的变量进行比较。

    XPath 表达式的结果是 Sequence。目前,XJ 支持有限形式的泛型(如 Java 5.0 中一样)。因此,程序员可以声明一个 Sequence<region> 类型的变量。编绎器确保 XPath 表达式的结果满足此类型。您可以从 Sequence 获得 XMLCursor。不管出于何种目的,您都可以将 XMLCursor 作为 java.util.Iterator 使用,只是您也能够以泛型形式使用它。XMLCursor 是泛型的,因此 region r = i.next() 不需要强制转换,因为编绎器了解 i 是 XMLCursor<region> 类型。最后需要注意的是,XJ 支持 XML 元素的 自动拆箱。因此,String s = r[| /name |] 这行代码(它提取 r 的 name 子元素)是有效的,因为编绎器可以推算出 name 元素具有 xsd:string 类型的内容,并且它将自动生成将该值作为一个 java.lang.String 提取出来的代码。

    结束语
    将 XML 支持集成到 Java 语言具有很多优势。它允许编绎器在早期检测错误并将它们报告给程序员。当 XML Schemas 改变时,编绎器能够检测到程序需要修改的那些部分。而且,编绎器能够选择 XML 的运行时表示以匹配 XML 的使用,从而使 XML 数据导航实现最优。所有这些优势都是诸如 DOM 之类的运行时 API 所不可能具备的,而且现在只存在于一些有限范围内的数据绑定方法(如 JAXB)当中。下载 XJ 程序包并尝试这些功能,我们就可以知道使用 XML 能否令编程工作变得更容易。

    参考资料

    您可以参阅本文在 developerWorks 全球站点上的 英文原文。


    从 IBM alphaWorks 下载 XJ 程序包,这里也包含专门介绍 emerging XML technologies 的页面。


    想要了解更多 XJ 语言的背景知识?请访问 XJ Research 站点,它包括一个 指南。


    您可以下载 XJ 手册 和一篇 技术论文(位于 WWW 2005)。


    阅读来自 HP Labs 的 报告,该报告概述了在 Java 中处理 XML 的一些当前方法存在的问题。


    要想了解更多有关 XPath 的内容,可从 W3C 的 XPath Recommendation 开始。也可以查看 Bertrand Portier 撰写的“Get Started with XPath”(developerWorks,2004 年 5 月)。


    要想大致了解 ECMAScript for XML (E4X),请阅读分为两个部分的 developerWorks 系列“AJAX and scripting Web services with E4X”(developerWorks,2005 年 4 月):
    第 1 部分 展示如何使用 E4X 来实现 Web 服务客户机。
    第 2 部分 演示 E4X 脚本如何用来实现使用 E4XProvider 的 Axis 下的 Web 服务。


    在 developerWorks 的 XML 和 Java 技术 专区可找到大量关于 XML 和 Java 技术的参考资料。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    重拾英语...

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2005/7/20 11:56:00
     
     GoogleAdSense双鱼座1981-2-28
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 XML基础 』的所有贴子 点击这里发送电邮给Google AdSense 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/4 23:15:14

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    6,234.375ms