| |
开发xslt解决方案可以很简单,只需要少量的工作执行转换。但是,有时候源文档和目标文档是比较复杂的,不同的。很多这种情况下,复杂的转换是通过等价的xslt复杂转换实现的。
有些转换使用普通的xslt功能是没法做到的。这种情况下,你可以使用apache xalan xslt引擎和自定义的java扩展在你的样式表里加入新函数。
一个例子 让我们从测试一个简单的例子开始吧。假设你正在转换一个xml文档,你需要在转换过程中执行很多高级的操作。你也许需要参考历遍一个数据库中的表或者访问一个web服务。这些函数很简单,但是xslt没有直接提供。
我们假设:有了一个简单的定购xml文档,如清单1所示。那么问题是:我们的转换过程需要翻转description元素中的字符。也许,它不符合现实世界中的情况,但是它可以演示了。
清单1:order.xml 〈order〉 〈items〉 〈item〉 〈sku〉19723〈/sku〉 〈description〉mechawidget flange〈/description〉 〈/item〉 〈item〉 〈sku〉87123〈/sku〉 〈description〉hydrafluant magnet〈/description〉 〈/item〉 〈item〉 〈sku〉662354〈/sku〉 〈description〉generic rubber seal〈/description〉 〈/item〉 〈item〉 〈sku〉967623〈/sku〉 〈description〉fluxating plasmatron〈/description〉 〈/item〉 〈/items〉 〈/order〉 解决方法
我们的解决方法是使用apache xalan xsl 处理器,并从它扩展出一个java类。这个java组件实现字符串数据的转换工作。xsl样式表访问这个java类,把xml数据传进去,在xml结果文档中显示返回值。每一步都列在下面了。
java部分 为了解决这个问题,我们首先需要写一个完成这个工作的java代码。既然这样,我们将使用一个简单的字符串翻转类,如清单2所示:
清单2:reverse.java
public class reverse { public static string reverse(string str) { string retval = ""; char[] b = new char[str.length()]; str.getchars(0, str.length(), b, 0); for (int i = (b.length - 1); i 〉= 0; i--) { retval += b[i]; } return retval; } }
这个类只有一个静态方法:reverse。这个方法的有一个string参数,返回一个字符串。这个函数将翻转字符串:从string类从读取字符到一个字符数组,然后从数组的尾部历遍字符。
xslt部分 为了在xsl样式表中使用java类,你需要声明一个xml命名空间。这个命名空间会识别调用java类的格式。这里有3个不同的命名空间的格式供你使用:我们演示其中一个,java格式如下:
xmlns:java=http://xml.apache.org/xalan/java
除了要声明java命名空间外,我们还需要设置〈xsl:stylesheet〉 元素的exclude-result-prefixes属性。这个属性会避免java命名空间出现在输出文档里。
为了在xsl样式表里正确地调用java组件,你需要指定类,方法和传入的参数。类必须以命名空间为前缀。比如,调用我们reverse类的reverse()方法,就要这样做:
〈xsl:value-of select="java:reverse.reverse(′this is a test′)" /〉
传入的值可以是一个静态的值(同上)或xml文档里的值。清单3列出了我们的xsl样式表,它包含了命名空间的声明,exclude-result-prefixes属性和〈description〉元素的值:调用reverse()方法。
清单3:order.xsl 〈?xml version="1.0"?〉 〈xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:java="http://xml.apache.org/xalan/java" exclude-result-prefixes="java"〉 〈xsl:output method="xml"/〉 〈xsl:template match="/order"〉 〈neworder〉 〈xsl:apply-templates/〉 〈/neworder〉 〈/xsl:template〉 〈xsl:template match="items/item"〉 〈item〉 〈sku〉〈xsl:value-of select="./sku" /〉〈/sku〉 〈description〉〈xsl:value-of select="java:reverse.reverse(./description)" /〉 〈/description〉 〈/item〉 〈/xsl:template〉 〈/xsl:stylesheet〉
可重用组件 在样式表里使用java类的部分价值是允许你重用java组件。举例说,如果你有了一个业务逻辑或者访问数据仓库或企业应用的信息的类,那么在你的xsl应用中的重用就很强大了。同样,你可以重用为其他企业应用的xsl创建的java扩展。
|
|