我试图仅在元素不存在的情况下向元素添加兄弟元素。
这是我的XML:
<?xml version='1.0' encoding='UTF-8'?>
<domain xmlns="http://xmlns.oracle.com/weblogic/domain" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/security/xacml http://xmlns.oracle.com/weblogic/security/xacml/1.0/xacml.xsd http://xmlns.oracle.com/weblogic/security/providers/passwordvalidator http://xmlns.oracle.com/weblogic/security/providers/passwordvalidator/1.0/passwordvalidator.xsd http://xmlns.oracle.com/weblogic/domain http://xmlns.oracle.com/weblogic/1.0/domain.xsd http://xmlns.oracle.com/weblogic/security http://xmlns.oracle.com/weblogic/1.0/security.xsd http://xmlns.oracle.com/weblogic/security/wls http://xmlns.oracle.com/weblogic/security/wls/1.0/wls.xsd">
<security-configuration>
<realm>
<sec:authentication-provider xsi:type="wls:default-authenticatorType">
<wls:use-retrieved-user-name-as-principal>true</wls:use-retrieved-user-name-as-principal>
</sec:authentication-provider>
<sec:authentication-provider xsi:type="wls:default-identity-asserterType">
<sec:active-type>AuthenticatedUser</sec:active-type>
</sec:authentication-provider>
</realm>
</security-configuration>
</domain>
所需的输出应为:
<domain xmlns="http://xmlns.oracle.com/weblogic/domain" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/security/xacml http://xmlns.oracle.com/weblogic/security/xacml/1.0/xacml.xsd http://xmlns.oracle.com/weblogic/security/providers/passwordvalidator http://xmlns.oracle.com/weblogic/security/providers/passwordvalidator/1.0/passwordvalidator.xsd http://xmlns.oracle.com/weblogic/domain http://xmlns.oracle.com/weblogic/1.0/domain.xsd http://xmlns.oracle.com/weblogic/security http://xmlns.oracle.com/weblogic/1.0/security.xsd http://xmlns.oracle.com/weblogic/security/wls http://xmlns.oracle.com/weblogic/security/wls/1.0/wls.xsd">
<security-configuration>
<realm>
<sec:authentication-provider xsi:type="wls:default-authenticatorType">
<wls:use-retrieved-user-name-as-principal>true</wls:use-retrieved-user-name-as-principal>
</sec:authentication-provider>
<sec:authentication-provider xsi:type="wls:default-identity-asserterType">
<sec:active-type>AuthenticatedUser</sec:active-type>
</sec:authentication-provider>
<!-- Just adding this element -->
<sec:authentication-provider xmlns:ext="http://xmlns.oracle.com/weblogic/security/extension" xsi:type="ext:session-authenticatorType">
<sec:name>SessionAuthenticator</sec:name>
<sec:control-flag>SUFFICIENT</sec:control-flag>
</sec:authentication-provider>
</realm>
</security-configuration>
</domain>
这种转换需要重新运行,因此我只需添加新元素(如果它不存在)。
这是我尝试使用的XLST:
<xsl:stylesheet version="1.0" xmlns:bi="http://xmlns.oracle.com/weblogic/domain"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="http://xmlns.oracle.com/weblogic/security"
xmlns:wls="http://xmlns.oracle.com/weblogic/security/wls">
<xsl:output method="xml" version="1.0" encoding='UTF-8' indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<!-- Identity transform -->
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<!-- match the existing child of realm -->
<xsl:template match="bi:realm/sec:authentication-provider[@xsi:type='wls:default-identity-asserterType']">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<!-- If the element doesn't exist already add it as a sibling -->
<xsl:if test="not(bi:realm/sec:authentication-provider[@xsi:type='ext:session-authenticatorType'])">
<sec:authentication-provider xmlns:ext="http://xmlns.oracle.com/weblogic/security/extension" xsi:type="ext:session-authenticatorType">
<sec:name>SessionAuthenticator</sec:name>
<sec:control-flag>SUFFICIENT</sec:control-flag>
</sec:authentication-provider>
</xsl:if>
</xsl:template>
运行此转换时,会添加所需的元素。然而问题是这不可重新运行。每次运行时都会忽略检查是否存在新元素。有什么想法吗?
答案 0 :(得分:2)
您的模板与sec:authentication-provider
元素匹配:
match="bi:realm/sec:authentication-provider[...]"
因此,在模板中,上下文节点是匹配的sec:authentication-provider
元素。因此,在执行测试时,您需要从该上下文继续。你目前的考试
test="not(bi:realm/sec:authentication-provider[@xsi:type='ext:session-authenticatorType'])"
仅在上下文节点是bi:realm
的父节点时才有效,即bi:security-configuration
。由于上下文节点是sec:authentication-provider
元素,并且您想测试兄弟节点,因此您的测试应如下所示:
test="not(../sec:authentication-provider[@xsi:type='ext:session-authenticatorType'])"
在实践中,如果我没有弄错的话,你正在测试的兄弟姐妹总是来在匹配的元素之后。因此,您可以使用following-sibling::
代替../
。