当前位置: 首页 > 知识库问答 >
问题:

使用XSLT修改web.xml并维护模式有效性

龙欣德
2023-03-14

根据Java Servlet规范,“servlet-mapping”元素必须跟在“Servlet”之后(如果有的话),而“Servlet”元素又必须跟在“listener”元素之后(如果有的话),依此类推。

那么,只有在“servlet-mapping”还不存在的情况下,我才能在所有其他“servlet”元素之后添加一个“servlet-mapping”元素。

下面是一个配对的web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  version="2.5"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
      <param-name>debug</param-name>
      <param-value>0</param-value>
    </init-param>
    <init-param>
      <param-name>listings</param-name>
      <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <init-param>
      <param-name>fork</param-name>
      <param-value>false</param-value>
    </init-param>
    <init-param>
      <param-name>xpoweredBy</param-name>
      <param-value>false</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>/jsp/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
  </servlet-mapping>
</web-app>

这里是我的XSLT,不幸的是,它将“servlet-mapping”元素放在web.xml的开头(如果还不存在的话):

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:jee="http://java.sun.com/xml/ns/javaee"
        xmlns="http://java.sun.com/xml/ns/javaee">
        <xsl:output method="xml" encoding="UTF-8"/>

        <xsl:param name="version.jsp.servlet.name" select="'jsp'"/>
        <xsl:param name="version.jsp.url.pattern" select="'/jsp/*'"/>

        <xsl:template match="@*|node()">
                <xsl:copy>
                        <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
        </xsl:template>

        <xsl:template match="jee:web-app">
                <xsl:copy>
                        <xsl:apply-templates select="@*"/>

                        <xsl:if test="not(jee:servlet-mapping[jee:servlet-name=$version.jsp.servlet.name and jee:url-pattern=$version.jsp.url.pattern])">
                                <xsl:message>Adding jsp servlet-mapping</xsl:message>
                                <xsl:element name="servlet-mapping">
                                        <xsl:element name="servlet-name">
                                                <xsl:value-of select="$version.jsp.servlet.name"/>
                                        </xsl:element>
                                        <xsl:element name="url-pattern">
                                                <xsl:value-of select="$version.jsp.url.pattern"/>
                                        </xsl:element>
                                </xsl:element>
                        </xsl:if>

                        <xsl:apply-templates select="node()"/>
                </xsl:copy>
        </xsl:template>
</xsl:stylesheet>

我尝试在XPath表达式中使用“follows-sibling”,但没有成功,如下所示:

not(jee:servlet[position()=last()]/following-sibling::jee:servlet-mapping[jee:servlet-name=$version.jsp.servlet.name and jee:url-pattern=$version.jsp.url.pattern])

我还需要在XML中添加一个“filter”元素,然后添加一个“filter-mapping”元素,但是,在这种情况下,如果“icon”、“display-name”、“description”、“distributable”和“context-param”元素存在的话,我显然需要在它们之后添加它们。

如果前面必需的元素存在,我该如何构造一个XPath表达式来解释这些元素呢?

共有1个答案

艾安和
2023-03-14

如果将xsl:If放在apply-templates之后,它应该可以工作。

但可能添加这样的模板也会对您有帮助:

<!-- It's the last servlet of the input -->
<xsl:template match="jee:servlet[not(following-sibling::jee:servlet)]">
    <!-- First do as usual and copy the servlet -->
    <xsl:next-match/>
    <!-- Then test if you need to output some specific mapping -->
    <xsl:if test="not(jee:servlet-mapping[jee:servlet-name=$version.jsp.servlet.name and jee:url-pattern=$version.jsp.url.pattern])">
    ...
    </xsl:if>
 </xsl:template>

但是在您的问题中使用position()不能像您希望的那样工作,因为您需要的是“上下文中的最后一个servlet”,而不是“仅当它是上下文中的最后一个元素时的servlet”。我认为通过模板示例,您将能够解决“过滤器案例”。

 类似资料:
  • 一个专有的程序,我正在使用压缩和提取某些文件,而不改变文件的修改日期时解压缩。我也创建了我自己的压缩和提取工具,基于源代码在我们的程序,但当我解压文件,修改日期所有压缩文件显示与解压时间和日期。下面是我提取的代码: { 我相信除了复制inputstream/outputstream之外,还有一种更好的方法可以做到这一点。我确信这是罪魁祸首,因为使用winRAR进行提取不会更改压缩文件的日期。

  • SENTINEL SET command 例如: SENTINEL SET objects-cache-master down-after-milliseconds 1000

  • mysqlcheck客户端可以检查和修复MyISAM表。它还可以优化和分析表。 mysqlcheck的功能类似myisamchk,但其工作不同。主要差别是当mysqld服务器在运行时必须使用mysqlcheck,而myisamchk应用于服务器没有运行时。使用mysqlcheck的好处是不需要停止服务器来检查或修复表。 Mysqlcheck为用户提供了一种方便的使用SQL语句CHECK TABLE

  • 如何在restasured中设置会话属性?在我的应用程序代码中,我们有如下内容 String userId = request.getSession().getAttribute(“userid”) 如何在此处将 userId 设置为会话属性(在重新保证的测试用例中)? 如何为所有请求(多个后续请求)维护同一会话? 当我发送多个请求时,它认为每个请求都是新的,会话从服务器端失效,我想在后续调用之间

  • Im目前使用XHTMLImporterImpl版本8.0和Docx4j8.23 这是我的转换代码

  • Navicat 为维护 Oracle 用户提供完整的解决方案。 在对象选项卡中选择用户。 右击已选择的用户。 选择“维护”,然后从弹出式菜单中选择一个维护选项。 选项 描述 密码过期 设置用户的密码为过期。 锁定帐号 锁定用户的帐号和禁用访问。 解除锁定帐号 解除锁定用户的帐号和启用访问。