1 / 41

J2EE —— 第 7 章 Extensible Stylesheet Language Transformations (XSLT)

J2EE —— 第 7 章 Extensible Stylesheet Language Transformations (XSLT). XSL 、 XSLT 和 XPath 简介. XSL-FO: 字体大小、页面布局、对象显示 XSLT: 从 XML 到某种其它格式的转换 XPath: 指定通向某个元素的路径 javax.xml.transform javax.xml.transform.dom javax.xml.transform.sax javax.xml.transform.stream. XPath 如何工作.

lilac
Download Presentation

J2EE —— 第 7 章 Extensible Stylesheet Language Transformations (XSLT)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. J2EE——第7章 Extensible Stylesheet Language Transformations (XSLT)

  2. XSL、XSLT和XPath简介 • XSL-FO:字体大小、页面布局、对象显示 • XSLT:从XML到某种其它格式的转换 • XPath:指定通向某个元素的路径 • javax.xml.transform • javax.xml.transform.dom • javax.xml.transform.sax • javax.xml.transform.stream

  3. XPath如何工作 • XPath规范定义了一个抽象文档模型,该文档模型定义了几种类型的节点:Root, Element,Text, Attribute,Comment Processing instruction, Namespace • XSLT/XPath数据模型:包含各种节点的树 <xsl:template match="//LIST"> ... </xsl:template>

  4. 基本XPath寻址 • 正斜杠(/)用作路径分隔符 • 从文档的根开始的绝对路径以/开始 • 从指定位置开始的相对路径可以以任何其它符号开始 • 双句点(..)表示当前节点的父节点 • 单句点(.)表示当前节点

  5. 基本XPath表达式 • PROJECT[.=“MyProject”] • PROJECT[STATUS] • PROJECT[STATUS=“Critical”] • LIST[@type=“ordered”][3] • LIST[3][@type=“ordered”] • *匹配任何Element节点 • node()匹配任何类型的任何节点 • @*匹配任何属性节点 • /HEAD/LIST//PARA

  6. XPath数据类型和运算符

  7. 元素的字符串值 <PARA>This paragraph contains a <B>bold</B> word</PARA> • PARA/text() • This paragraph contains a bold word

  8. XPath函数 • 节点集函数 • id(…) • 位置函数 • last():如/HEAD[last()] • position():如/HEAD[position()<=5] • count(…):如/HEAD[count(HEAD)=0]

  9. 字符串函数 • concat(string, string, ...): • contains(string1, string2 • substring-before(string1, string2) • substring-after(string1, string2) • substring(string, idx) • substring(string, idx, len) • string-length() • string-length(string) • normalize-space() • normalize-space(string) • translate(string1, string2, string3):

  10. 其它函数 • Boolean函数 • not(...) • true() • false() • lang(string) • 数值函数 • sum(…) • floor(N) • ceiling(N) • round(N)

  11. 其它函数 • 转换函数 • string(…) • boolean(…) • number(…) • 名称空间函数 • local-name(), local-name(…) • namespace-uri(), namespace-uri(..) • name(), name(…)

  12. 把DOM作为XML文件写出 import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer transformer = tFactory.newTransformer(); DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(System.out); transformer.transform(source, result);

  13. 写出DOM的子树 import org.w3c.dom.Node; import org.w3c.dom.NodeList; NodeList list = document.getElementsByTagName("slide"); Node node = list.item(0); DOMSource source = new DOMSource(node); <?xml version="1.0" encoding="UTF-8"?> <slide type="all"> <title>Wake up to WonderWidgets!</title> </slide>

  14. 从任一数据结构生成XML xmozillanickname: Fred mail: Fred@barneys.house xmozillausehtmlmail: TRUE givenname: Fred sn: Flintstone telephonenumber: 999-Quarry homephone: 999-BedrockLane facsimiletelephonenumber: 888-Squawk pagerphone: 777-pager cellphone: 555-cell

  15. 准备工作 import org.xml.sax.*; import org.xml.sax.helpers.AttributesImpl; public class AddressBookReader implements XMLReader { ContentHandler handler; String nsu = ""; // NamespaceURI Attributes atts = new AttributesImpl(); String rootElement = "addressbook"; String indent = "\n "; // for readability! public void parse (InputSource input) throws IOException, SAXException{ java.io.Reader r = input.getCharacterStream(); BufferedReader br = new BufferedReader(r);

  16. 生成SAX事件 if (handler==null) { throw new SAXException("No content handler"); } handler.startDocument(); handler.startElement(nsu, rootElement, rootElement, atts); output("nickname", "xmozillanickname", line); line = br.readLine(); ... output("cell", "cellphone", line); handler.ignorableWhitespace("\n".toCharArray(), 0, 1); handler.endElement(nsu, rootElement, rootElement); handler.endDocument();

  17. 元素SAX事件 void output(String name, String prefix, String line) throws SAXException { int startIndex = prefix.length() + 2; // 2=length of ": " String text = line.substring(startIndex); int textLength = line.length() - startIndex; handler.ignorableWhitespace(indent.toCharArray(), 0, indent.length()); handler.startElement(nsu, name, name /*"qName"*/, atts); handler.characters(text.toCharArray(), startIndex, textLength); handler.endElement(nsu, name, name); }

  18. 把解析器用作SAXSource import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import javax.xml.transform.sax.SAXSource; AddressBookReader saxReader = new AddressBookReader(); Transformer transformer = tFactory.newTransformer(); FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); InputSource inputSource = new InputSource(br); SAXSource source = new SAXSource(saxReader, inputSource); StreamResult result = new StreamResult(System.out); transformer.transform(source, result);

  19. 用XSLT转换XML数据 <?xml version="1.0"?> <ARTICLE> <TITLE>A Sample Article</TITLE> <SECT>The First Major Section <PARA>This section will introduce a subsection.</PARA> <SECT>The Subsection Heading <PARA>This is the text of the subsection. </PARA> </SECT> </SECT> </ARTICLE>

  20. 编写XSLT转换 <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <html><body> <xsl:apply-templates/> </body></html> </xsl:template> … </xsl:stylesheet> • 使用html输出方式时, &lt;将输出为<

  21. 处理<TITLE>和<SECT> <xsl:template match="/ARTICLE/TITLE"> <h1 align="center"><xsl:apply-templates/></h1> </xsl:template> <xsl:template match="/ARTICLE/SECT"> <h2><xsl:apply-templates select="text()|B|I|U|DEF|LINK"/></h2> <xsl:apply-templates select="SECT|PARA|LIST|NOTE"/> </xsl:template> <xsl:template match="/ARTICLE/SECT/SECT"> <h3><xsl:apply-templates select="text()|B|I|U|DEF|LINK"/></h3> <xsl:apply-templates select="SECT|PARA|LIST|NOTE"/> </xsl:template> </xsl:stylesheet>

  22. 处理过深嵌套错误和<PARA> <xsl:template match="/ARTICLE/SECT/SECT/SECT"> <xsl:message terminate="yes"> Error: Sections can only be nested 2 deep. </xsl:message> </xsl:template> <xsl:template match="PARA"> <p><xsl:apply-templates/></p> </xsl:template> </xsl:stylesheet>

  23. 编写基本的程序 import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamResult; File stylesheet = new File(argv[0]); File datafile = new File(argv[1]); DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse(datafile); StreamSource stylesource = new StreamSource(stylesheet); Transformer transformer = Factory.newTransformer(stylesource); DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(System.out); transformer.transform(source, result);

  24. 转换结果 <html> <body> <h1 align="center">A Sample Article</h1> <h2>The First Major Section </h2> <p>This section will introduce a subsection.</p> <h3>The Subsection Heading </h3> <p>This is the text of the subsection. </p> </body> </html>

  25. 剪裁空白 <xsl:strip-space elements="SECT"/> <xsl:template match="text()"> <xsl:value-of select="normalize-space()"/> </xsl:template> <html> <body> <h1 align="center">A Sample Article</h1> <h2>The First Major Section</h2> <p>This section will introduce a subsection.</p> <h3>The Subsection Heading</h3> <p>This is the text of the subsection.</p> </body> </html>

  26. 处理其余的结构元素 <?xml version="1.0"?> <ARTICLE> <TITLE>A Sample Article</TITLE> <SECT>The First Major Section ... </SECT> <SECT>The Second Major Section <PARA>This section adds a LIST and a NOTE. </PARA> <PARA>Here is the LIST: <LIST type="ordered"> <ITEM>Pears</ITEM> <ITEM>Grapes</ITEM> </LIST> </PARA> <PARA>And here is the NOTE: <NOTE>Don't forget to go to the hardware store on your way to the grocery! </NOTE> </PARA> </SECT> </ARTICLE>

  27. 修改XSLT <xsl:template match="PARA"> <p><xsl:apply-templates select="text()|B|I|U|DEF|LINK"/></p> <xsl:apply-templates select="PARA|LIST|NOTE"/> </xsl:template> <xsl:template match="LIST"> <xsl:if test="@type='ordered'"> <ol> <xsl:apply-templates/> </ol> </xsl:if> <xsl:if test="@type='unordered'"> <ul> <xsl:apply-templates/> </ul> </xsl:if> </xsl:template> </xsl:stylesheet>

  28. 处理<ITEM>和<NOTE> <xsl:template match="ITEM"> <li><xsl:apply-templates/> </li> </xsl:template> <xsl:template match="NOTE"> <blockquote><b>Note:</b><br/> <xsl:apply-templates/> </blockquote> </xsl:template> • 当多个模板都匹配时,最后出现的模板优先

  29. 运行结果 … <h2>The Second Major Section</h2> <p>This section adds a LIST and a NOTE.</p> <p>Here is the LIST:</p> <ol> <li>Pears</li> <li>Grapes</li> </ol> <p>And here is the NOTE:</p> <blockquote> <b>Note:</b> <br>Don't forget to go to the hardware store on your way to the grocery! </blockquote>

  30. 处理内联(内容)元素 <SECT>The <I>Third</I> Major Section <PARA>In addition to the inline tag in the heading, this section defines the term <DEF>inline</DEF>, which literally means "no line break". It also adds a simple link to the main page for the Java platform (<LINK>http://java.sun.com</LINK>), as well as a link to the <LINK target="http://java.sun.com/xml">XML</LINK> page. </PARA> </SECT>

  31. 修改XSLT <xsl:template match="DEF"> <i><xsl:apply-templates/></i> </xsl:template> <xsl:template match="B|I|U"> <xsl:element name="{name()}"> <xsl:apply-templates/> </xsl:element> </xsl:template>

  32. 处理<LINK> <xsl:template name="htmLink"> <xsl:param name="dest" select="UNDEFINED"/> <xsl:element name="a"> <xsl:attribute name="href"> <xsl:value-of select="$dest"/> </xsl:attribute> <xsl:apply-templates/> </xsl:element> </xsl:template>

  33. 调用命名模板 <xsl:template match="LINK"> <xsl:if test="@target"> <xsl:call-template name="htmLink"> <xsl:with-param name="dest" select="@target"/> </xsl:call-template> </xsl:if> <xsl:if test="not(@target)"> <xsl:call-template name="htmLink"> <xsl:with-param name="dest"> <xsl:apply-templates/> </xsl:with-param> </xsl:call-template> </xsl:if> </xsl:template>

  34. 运行结果 ... <h2>The <I>Third</I> Major Section </h2> <p>In addition to the inline tag in the heading, this section defines the term <i>inline</i>, which literally means "no line break". It also adds a simple link to the main page for the Java platform (<a href="http://java. sun.com">http://java.sun.com</a>), as well as a link to the <a href="http://java.sun.com/xml">XML</a> page. </p>

  35. XSLT的其它功能 • include, import • for-each • 生成编号 • 格式化编号 • 输出排序 • 基于模式的模板 <apply-template mode=“…”>

  36. 用Xalan从命令行转换 java org.apache.xalan.xslt.Process -IN article3.xml -XSL article3.xsl -OUT article3.html

  37. 用过滤器链连接转换 File stylesheet1 = new File(argv[0]); File stylesheet2 = new File(argv[1]); File datafile = new File(argv[2]); BufferedInputStream bis = new BufferedInputStream(newFileInputStream(datafile)); InputSource input = new InputSource(bis); SAXParserFactory.newInstance(); spf.setNamespaceAware(true); SAXParser parser = spf.newSAXParser(); XMLReader reader = parser.getXMLReader(); SAXTransformerFactory stf = (SAXTransformerFactory) TransformerFactory.newInstance(); XMLFilter filter1 = stf.newXMLFilter( new StreamSource(stylesheet1)); XMLFilter filter2 = stf.newXMLFilter( new StreamSource(stylesheet2)); filter1.setParent(reader); filter2.setParent(filter1); StreamResult result = new StreamResult(System.out); Transformer transformer = stf.newTransformer(); SAXSource transformSource = new SAXSource(filter2, input); transformer.transform(transformSource, result);

  38. 了解过滤器如何工作

  39. 测试程序 <?xml version="1.0"?> <Article> <ArtHeader> <Title>Title of my (Docbook) article</Title> </ArtHeader> <Sect1> <Title>Title of Section 1.</Title> <Para>This is a paragraph.</Para> </Sect1> </Article>

  40. 作为filter1的xsl文件 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform“ version="1.0“> <xsl:output method="xml"/> <xsl:template match="/"> <ARTICLE> <xsl:apply-templates/> </ARTICLE> </xsl:template> <xsl:template match="/Article/ArtHeader/Title"> <TITLE> <xsl:apply-templates/> </TITLE> </xsl:template> <xsl:template match="//Sect1"> <SECT><xsl:apply-templates/></SECT> </xsl:template> <xsl:template match="Para"> <PARA><xsl:apply-templates/></PARA> </xsl:template> </xsl:stylesheet>

  41. 过滤器链连接转换结果 <html> <body> <h1 align="center">Title of my (Docbook) article</h1> <h2>Title of Section 1.</h2> <p>This is a paragraph.</p> </body> </html>

More Related