我一直在寻找一种方法来检查 Web 应用程序部署描述符 (web.xml) 中是否存在特定的“servlet-mapping”,如果未找到则添加它,同时保持 XSLT 1.0 的架构有效性,但是,我'我会睁一只眼闭一只眼地试图弄清楚它并继续兜圈子,这可能会使它变得更加困难。
根据 Java Servlet 规范,“servlet-mapping”元素必须跟在“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 表达式中使用“following-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 中添加一个“过滤器”元素,然后是一个“过滤器映射”元素,但是,在这种情况下,我显然需要在所有“图标”、“显示名称”、“描述”之后添加它们, “distributable”和“context-param”元素(如果它们存在的话)。
如果前面的必需元素完全存在,我将如何构造一个 XPath 表达式来解释它们?