<x:parse>标记有多种格式,取决于用户希望的分解类型。这一项操作最基本的格式使用以下语法:
<x:parse xml="expression" var="name" scope="scope"    filter="expression" systemId="expression"/>
在这五种属性中,只有xml属性是需要的,其值应该是包含要分解的XML文件的字符串,或者是java.io.Reader实例,通过它可以读取要被分解的文件。此外,您可以使用以下语法,根据<x:parse>标记的主体内容来规定要被分解的文件:
<x:parse var="name" scope="scope"    filter="expression" systemId="expression">  body content</x:parse>
var和scope属性规定存储分解后的文件的scoped变量。然后xml库中的其它标记可以使用这一变量来运行其它操作。注意,当var和 scope 属性存在时,JSTL用于表示分解后的文件的数据结构类型以实施为导向,从而厂商可以对其进行优化。 
如果应用程序需要对JSTL提供的分解后的文件进行处理,它可以使用另一种格式的<x:parse>,它要求分解后的文件坚持使用一个标准接口。在这种情况下,该标记的语法如下: 
<x:parse xml="expression" varDom="name" scopeDom="scope"    filter="expression" systemId="expression"/>
当您使用<x:parse>的这一版本时,表示分解后的XML文件的对象必须使用org.w3c.dom.Document接口。当根据<x:parse>中的主体内容来规定XML文件时,您还可以使用varDom和scopeDom属性来代替var 和 scope属性,语法如下:
<x:parse varDom="name" scopeDom="scope"    filter="expression" systemId="expression">  body content</x:parse>
其它两个属性filter 和 systemId 可以实现对分解流程的精确控制。filter 属性规定org.xml.sax.XMLFilter类的一个实例,以在分解之前对文件进行过滤。如果要被分解的文件非常大,但目前的工作只需要处理一小部分内容时这一属性尤其有用。systemId属性表示要被分解的文件的URI并解析文件中出现的任何相关的路径。当被分解的XML文件使用相关的URL来引用分解流程中需要接入的其它文件或资源时需要这种属性
清单1展示了<x:parse> 标记的使用,包括与 <c:import>的交互。此处<c:import> 标记用于检索众所周知的Slashdot Web 网站的RDF Site Summary (RSS)反馈,然后使用<x:parse>分解表示RSS 反馈的XML文件,表示分解后的文件的以实施为导向的数据结构被保存到名为rss的变量(带有page 范围)中。 
清单1:<x:parse>与<c:import>的交互
<c:import var="rssFeed" url="http://slashdot.org/slashdot.rdf"/><x:parse var="rss" xml="${rssFeed}"/>
转换XML
XML通过XSL样式表来转换。JSTL使用<x:transform>标记来支持这一操作。与<x:parse>的情况一样,<x:transform> 标记支持多种不同的格式。<x:transform> 最基本的格式的语法是: 
<x:transform xml="expression" xslt="expression"    var="name" scope="scope"    xmlSystemId="expression" xsltSystemId="expression">  <x:param name="expression" value="expression"/>  ...</x:transform>
关于 RSSRDF Site Summary (RSS) 是许多以新闻为导向的网站公布的XML文件格式,它列出它们当前的标题,提供链接到相关文章的URL。 同样,它提供在Web上联合新闻的简单机制。关于RSS的更详细信息,请参阅参考资料。
此处,xml 属性规定要被转换的文件,xslt 属性规定定义这次转换的样式表。这两种属性是必要的,其它属性为可选。 
与<x:parse>的xml属性一样,<x:transform>的xml 属性值可以是包含XML文件的字符串,或者是接入这类文件的Reader。此外,它还可以采用 org.w3c.dom.Document 类或javax.xml.transform.Source 类的实例格式。最后,它还可以是使用<x:parse> 操作的var或varDom属性分配的变量值。 
而且,您可以根据<x:transform> 操作的主体内容来包含要被转换的XML文件。在这种情况下,<x:transform> 的语法是: 
<x:transform xslt="expression"    var="name" scope="scope"    xmlSystemId="expression" xsltSystemId="expression">  body content  <x:param name="expression" value="expression"/>  ...</x:transform>
在这两种情况下,规定XSL 样式表的xslt 属性应是字符串、Reader或javax.xml.transform.Source实例。 
如果var 属性存在,转换后的XML文件将分配给相应的scoped变量,作为org.w3c.dom.Document 类的一个实例。通常,scope属性规定这类变量分配的范围。 
<x:transform> 标记还支持将转换结果存储到javax.xml.transform.Result 类的一个实例中,而不是作为org.w3c.dom.Document的一个实例。如果var 和 scope 属性被省略,result对象规定作为result属性的值,<x:transform>标记将使用该对象来保存应用该样式表的结果。清单2中介绍了使用<x:transform> 的result属性的这两种语法的变化: 
清单2:使用result属性来提供javax.xml.transform.Result实例时,<x:transform>操作的语法变化

解决方案 »

  1.   

    <x:transform xml="expression" xslt="expression"    result="expression"    xmlSystemId="expression" xsltSystemId="expression">  <x:param name="expression" value="expression"/>  ...</x:transform><x:transform xslt="expression"    result="expression"    xmlSystemId="expression" xsltSystemId="expression">  body content  <x:param name="expression" value="expression"/>  ...</x:transform>
    无论您采用这两种<x:transform>格式中的那一种,您都必须从定制标记单独创建javax.xml.transform.Result对象。该对象自身作为result属性的值提供。 
    如果既不存在var 属性,也不存在result属性,转换的结果将简单地插入到JSP页面,作为处理<x:transform> 操作的结果。当样式表用于将数据从XML转换成HTML时尤其有用,如清单3所示: 
    清单3:在JSP页面直接显示转换的XML数据
    <c:import var="rssFeed" url="http://slashdot.org/slashdot.rdf"/><c:import var="rssToHtml" url="/WEB-INF/xslt/rss2html.xsl"/><x:transform xml="${rssFeed}" xslt="${rssToHtml}"/>
    在本例中,使用 <c:import> 标记来读取RSS反馈和适当的样式表。样式表的输出结果是HTML,通过忽略<x:transform>的var和result 属性来直接显示。图1显示了实例结果: 
    图1:清单3的输出结果
     
    与<x:parse>的systemId 属性一样,<x:transform>的xmlSystemId 和 xsltSystemId 属性用于解析XML文件中相关的路径。在这种情况下,xmlSystemId 属性应用于根据标记的 xml属性值提供的文件,而xsltSystemId 属性用于解析根据标记的xslt属性规定的样式表中的相关路径。 
    如果正在推动文件转换的样式表使用了参数,我们使用<x:param> 标记来规定这些参数。如果参数存在,那么这些标记必须在<x:transform> 标记主体内显示。如果根据主体内容规定了要被转换的XML文件,那么它必须先于任何 <x:param> 标记。 
    <x:param> 标记有两种必要的属性 -- name 和 value -- 就象本系列第2部分 和第3部分中讨论的<c:param> 和 <fmt:param> 标记一样。 
    处理XML内容
    XML文件的分解和转换操作都是基于整个文件来进行。但是,在您将文件转换成一种可用的格式之后,一项应用程序通常只对文件中包含的一部分数据感兴趣。鉴于这一原因,xml 库包括多个标记来接入和控制XML文件内容的各个部分。 
    如果您已经阅读了本系列第2部分(探讨核心),您将对这些xml 标记的名字非常熟悉。它们都基于JSTL core 库相应的标记。但是,这些core 库标记使用EL表达式,通过它们的value属性来接入JSP容器中的数据,而它们在xml 库中的副本使用XPath表达式,通过select属性接入XML文件中的数据。
    XPath是引用XML文件中元素及它们的属性值和主体内容的标准化符号。 正如其名字代表的一样,这种符号与文件系统路径的表示方法类似,使用短斜线来分开XPath语句的组分。这些组分对映于XML文件的节点,连续的组分匹配嵌套的Element。此外,星号可以用于作为通配符来匹配多个节点,括号内的表达式可以用于匹配属性值和规定索引。有多种在线参考资料介绍XPath和它的使用(见参考资料)。 
    要显示XML文件的数据的一个Element,使用<x:out> 操作,它与core 库的<c:out> 标记类似。 但是,<c:out> 使用名为value 和escapeXml的属性,<x:out> 的属性为select 和escapeXml: 
    <x:out select="XPathExpression" escapeXml="boolean"/>
    当然,两者的区别在于<x:out> 的select 属性值必须是XPath表达式,而<c:out> 的value 属性必须是EL表达式。两种标记的escapeXml 属性的意义是相同的。 
    清单4显示了<x:out> 操作的使用。注意,规定用于select 属性的XPath表达式由一个EL表达式规定为scoped变量,尤其是$rss。这一EL表达式根据将被求值的XPath语句来识别分解后的XML文件。该语句在此处查找名为title且父节点名为channel的Element,从而选择它找到的第一个Element(根据表达式尾部[1]索引规定)。这一<x:out> 操作的结果是显示这一Element的主体内容,关闭正在转义(Escaping)的XML字符。 
    清单4:使用<x:out>操作来显示XML Element的主体内容
    <c:import var="rssFeed" url="http://slashdot.org/slashdot.rdf"/><x:parse var="rss" xml="${rssFeed}"/><x:out select="$rss//*[name()='channel']/*[name()='title'][1]"   escapeXml="false"/>
    除了<x:out>之外,JSTL xml 库包括以下控制XML数据的标记: 
    · <x:set> ,向JSTL scoped 变量分配XPath表达式的值 
    · <x:if> ,根据XPath表达式的布尔值来条件化内容 
    · <x:choose>、<x:when>和<x:otherwise>, 根据XPath表达式来实施互斥的条件化 
    · <x:forEach> ,迭代根据XPath表达式匹配的多个Elements
    每个这些标记的操作与core库中相应的标记类似。例如,清单5中显示的<x:forEach>的使用, <x:forEach> 操作用于迭代XML文件中表示RSS反馈的所有名为item 的Element。注意,<x:forEach>主体内容中嵌套的两个<x:out> 操作中的XPath表达式与<x:forEach>标记正在迭代的节点相关。它们用于检索每个item element的子节点link 和 title。
      

  2.   

    先感谢hyq0077(hyq),我已收到jar包,可是运行之后,错误又成了这个样子,请大家看看
    type Exception reportmessage description The server encountered an internal error () that prevented it from fulfilling this request.exception javax.servlet.ServletException: org/jaxen/NamespaceContext
    org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:867)
    org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:800)
    org.apache.jsp.x_005fparse_jsp._jspService(x_005fparse_jsp.java:74)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:133)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:311)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:301)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:248)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
    root cause java.lang.NoClassDefFoundError: org/jaxen/NamespaceContext
    org.apache.taglibs.standard.tag.common.xml.ExprSupport.doStartTag(ExprSupport.java:101)
    org.apache.taglibs.standard.tag.el.xml.ExprTag.doStartTag(ExprTag.java:103)
    org.apache.jsp.x_005fparse_jsp._jspx_meth_x_out_0(x_005fparse_jsp.java:125)
    org.apache.jsp.x_005fparse_jsp._jspService(x_005fparse_jsp.java:64)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:133)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:311)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:301)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:248)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
    note The full stack trace of the root cause is available in the Tomcat logs.