没有重复的元素XSLT

时间:2017-12-01 02:40:27

标签: java xml xslt xslt-2.0 sax

我想插入以下安全约束

<security-constraint>
    <web-resource-collection>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>AcctAdminRole</role-name>
    </auth-constraint>
</security-constraint>
<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>default</realm-name>
</login-config>

在应用xslt的新XML中只使用一次,仅用于角色名:AcctAdminRole。 这是我的XML:

<web-app
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="BLA"
version="2.5">
    <listener>
        <listener-class>com.example</listener-class>
    </listener>
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>report.pdf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/config/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/spring/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

在这个xsl文件中,我控制它只会添加一次,但是它会多次添加,而且我不知道如何在角色名称为AcctAdminRole时应用。

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ee="http://java.sun.com/xml/ns/javaee"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="ee xs fn">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="ee:web-app">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:if test="not(security-constraint)">
                <security-constraint>
                    <web-resource-collection>
                        <url-pattern>/*</url-pattern>
                    </web-resource-collection>
                    <auth-constraint>
                        <role-name>AcctAdminRole</role-name>
                    </auth-constraint>
                </security-constraint>
                <login-config>
                    <auth-method>BASIC</auth-method>
                    <realm-name>default</realm-name>
                </login-config>
            </xsl:if>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

全部谢谢

1 个答案:

答案 0 :(得分:0)

如果要将XSLT应用于已具有security-constraint节点的XML,则需要考虑命名空间。您的XSLT正在将security-constraint添加到命名空间“http://java.sun.com/xml/ns/javaee”中,但xsl:if正在检查没有命名空间的security-constraint

有两种方法可以解决这个问题。一种方法是在xsl:if测试

中添加名称空间前缀
 <xsl:if test="not(ee:security-constraint)">

或者,当您使用XSLT 2.0时,您可以使用xpath-default-namespace来指示用于xpath表达式中任何未加前缀元素的命名空间

<xsl:stylesheet version="2.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ee="http://java.sun.com/xml/ns/javaee"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions" 
    xpath-default-namespace="http://java.sun.com/xml/ns/javaee"
    exclude-result-prefixes="ee xs fn">

您可能还想考虑在模板匹配中将测试放在security-constraint上。

试试这个XSLT

<xsl:stylesheet version="2.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ee="http://java.sun.com/xml/ns/javaee"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions" 
    xpath-default-namespace="http://java.sun.com/xml/ns/javaee"
    exclude-result-prefixes="ee xs fn">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="web-app[not(security-constraint)]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <security-constraint>
                <web-resource-collection>
                    <url-pattern>/*</url-pattern>
                </web-resource-collection>
                <auth-constraint>
                    <role-name>AcctAdminRole</role-name>
                </auth-constraint>
            </security-constraint>
            <login-config>
                <auth-method>BASIC</auth-method>
                <realm-name>default</realm-name>
            </login-config>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>