IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  XML | Web development  >

技巧: 根据 XML 内容设置 XSL 样式表

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Nicholas Chase (nicholas@nicholaschase.com), 总裁, Chase and Chase, Inc.

2002 年 5 月 01 日

使用可扩展样式表语言转换(Extensible Stylesheet Language Transformation(XSLT))通常是将 XML 数据从一种形式转换成另一种形式的最方便的方法,因为它使您具有很大的灵活性,而不必更改应用程序。然而,有时您可能会遇到意外困难,因为要使用的样式表是基于文档本身的内容。本篇技巧文章讨论了两种使您选择的样式表基于 XML 文档的方法 ― 样式表处理指令和数据本身。

本篇技巧文章使用 Apache 项目中的 JAXP 和 Xalan-Java。这些类也是 Java 2 SDK 1.4 的一部分,因此,如果您安装了 1.4,那么就不需要任何附加软件。

转换文档

转换文档的过程包括使用样式表作为其基础来创建一个 Transformer 对象、设置源文档和结果文档以及执行转换。在其最简单的形式中,它类似于清单 1. 执行转换中的代码。


清单 1. 执行转换
import java.io.File;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
public class ChooseStyleSheet {
   public static void main (String args[]) {
      try {
      TransformerFactory transformerFactory =
                          TransformerFactory.newInstance();
         StreamSource source = new StreamSource("scores.xml");
         StreamResult result = new StreamResult("result.xml");
         StreamSource style = new StreamSource("scores.xsl");
         Transformer transformer =
                       transformerFactory.newTransformer(style);
         transformer.transform(source, result);  
      } catch (Exception e) {
               e.printStackTrace();
      }
   }
}





回页首


关联样式表

表明文档的 XML 样式表的最简单方法是添加样式表处理指令并将样式表与文档关联。 在本例中,只要将一行添加到源文档(请参阅清单 2. 添加处理指令的样式表)。


清单 2. 添加处理指令的样式表
<?xml version="1.0"?>
<?xml-stylesheet href="scores.xsl" type="text/xsl"?>
<results showName="New Port Richey Open" location="New Port Richey, FL" showDate="7/31/01">
...
</results>

从这里,应用程序可以通过使用 TransformerFactorygetAssociatedStyleSheet() 方法(如清单 3. 获取关联的样式表所示)来检索信息。


清单 3. 获取关联的样式表所示
import java.io.File;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.Source;
public class ChooseStyleSheet {
   public static void main (String args[]) {
      try {
         TransformerFactory transformerFactory =
                          TransformerFactory.newInstance();
         StreamSource source = new StreamSource("scores.xml");
         StreamResult result = new StreamResult("result.xml");
         Source style = transformerFactory
                         .getAssociatedStylesheet(source, null, null, null);
         Transformer transformer =
                       transformerFactory.newTransformer(style);
         transformer.transform(source, result);
      } catch (Exception e) {
		e.printStackTrace();
      }
   }
}

请注意,该方法实际上有四个参数。其定义为:

getAssociatedStylesheet(Source source,
                        java.lang.String media,
                        java.lang.String title,
                        java.lang.String charset)

这允许您根据媒体、标题和字符集选择样式表。 例如,XML 文档读上去可能象清单 4. 多个样式表。


清单 4. 多个样式表
<?xml version="1.0"?>
<?xml-stylesheet href="scores.xsl" type="text/xsl"?>
<?xml-stylesheet href="scores_wap.xsl" type="text/xsl" media="phone"?>
<?xml-stylesheet href="scores_print.xsl" type="text/xsl" media="print"?>
<results showName="New Port Richey Open" location="New Port Richey, FL" showDate="7/31/01">
...
</results>

通过这种方法,可以对应用程序进行特别地选择,例如,印刷版本(请参阅清单 5. 选择特定媒体)。


清单 5. 选择特定媒体
...
         StreamSource source = new StreamSource("scores.xml");
         StreamResult result = new StreamResult("result.xml");
         Source style = transformerFactory
                         .getAssociatedStylesheet(source, "print", null, null);
         Transformer transformer =
                       transformerFactory.newTransformer(style);
...





回页首


根据数据选择样式表

另一方面,您可能想要根据文档中的数据精确地选择样式表。 在这种情况下,首先要解析文档并直接检索数据,然后使用数据来确定样式表。

例如,考虑一个处理多页并根据根元素名称选择样式表的应用程序。 精确地转换文件包括解析文档,然后确定根元素名称,如清单 6. 解析文档中所示。


清单 6. 解析文档
import java.io.File;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.Source;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class ChooseStyleSheet {
   public static void main (String args[]) {
      String rootName = null;
      try {
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
         Document doc = db.parse("scores.xml");
         Element root = doc.getDocumentElement();
         rootName = root.getNodeName();
      } catch (Exception e) {
         e.printStackTrace();
      }
      try {
         TransformerFactory transformerFactory =
                          TransformerFactory.newInstance();
         StreamSource source = new StreamSource("scores.xml");
         StreamResult result = new StreamResult("result.xml");
         String styleName = null;
         if (rootName.equals("results")){
             styleName = "scores.xsl";
         } else if (rootName.equals("entries")){
             styleName = "entries.xsl";
         }
         Transformer transformer = null;
         if (styleName == null) {
             transformer = transformerFactory.newTransformer();
         } else {
             StreamSource style = new StreamSource(styleName);
             transformer =  transformerFactory.newTransformer(style);
         }
         transformer.transform(source, result);
      } catch (Exception e) {
		e.printStackTrace();
      }
   }
}

这里的操作有两个主要步骤。首先,解析文档并获取根元素的名称,将该名称作为一个 String 值传入第二个 try-catch 块中。

在第二个 try-catch 块中,确定新样式表将是什么。 该示例仅显示两个选项,如果根元素不是这两个选项之一,那么样式表名保持为 null

从这里, 是创建实际 Transformer 对象的事情。如果选择了样式表,显然应该将它用于创建 style Source ,然后把该 Source 传递给 newTransformer() 方法以创建 Transformer 对象。反之,如果没有做任何选择,则您可以选择创建不带样式表的 Transformer 对象。这样做的结果是只传递源文档而源文档不会改变。





回页首


后继步骤

本篇技巧文章演示了使用 XML 文档中的数据确定要处理的样式表的简单方法。您可以扩充该原理以包括从其它资源(如数据库)中汲取的信息来确定样式表。 要使工作更进一步,可以使用 XML 文档中的信息来设置样式表中的参数, 或者甚至实时创建一个样式表并使用它来转换原始文档。



参考资料



关于作者

Nicholas Chase 参与了很多公司(如 Lucent Technologies、Sun Microsystems、Oracle 和 Tampa Bay Buccaneers 等)的网站开发。Nick 曾是一名高中物理教师、低辐射废物设备管理人员、在线科幻小说杂志编辑、多媒体工程师和 Oracle 讲师。 最近,他成为 Site Dynamics Interactive Communications(位于佛罗里达州克利尔沃特市)的首席技术官, 而且还是三本有关 Web 开发书籍的作者,包括 Java and XML From Scratch (Que) 和即将出版的 Primer Plus XML Programming (Sams)。他乐于听取读者的意见,可以通过 nicholas@nicholaschase.com与他联系。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款