我的输入XML如下。基本上,XML具有各种<servlet>
标记。我的要求是应用XSLT转换,该转换浏览<servlet-name>
标记并查看是否存在具有指定名称的特定servlet。如果它存在,那么我需要看到带有<param-name>
的特定servlet下的标记<B>
不存在。如果搜索到的具有特定<param-name>
的标签不存在,那么我将标签<B>NEW</B>
与该特定servlet的其他<B>
标签一起添加,否则我不执行任何操作。
输入XML
<web-app metadata-complete="true">
<servlet>
<servlet-name>AAA</servlet-name>
<servlet-class>com.AAA</servlet-class>
<B>
<param-name>port</param-name>
<param-value>8802</param-value>
</B>
<B>
<param-name>connectors-xml</param-name>
<param-value/>
</B>
<B>
<param-name>webservices-xml</param-name>
<param-value/>
</B>
<B>
<param-name>exposure-server</param-name>
<param-value/>
</B>
<some-tag>1</some-tag>
</servlet>
<servlet>
<servlet-name>BBB</servlet-name>
<servlet-class>com.BBB</servlet-class>
<B>
<param-name>port</param-name>
<param-value>8802</param-value>
</B>
<B>
<param-name>connectors-xml</param-name>
<param-value/>
</B>
<B>
<param-name>webservices-xml</param-name>
<param-value/>
</B>
<B>
<param-name>exposure-server</param-name>
<param-value/>
</B>
<some-tag>2</some-tag>
</servlet>
<C>
<D>
</D
</C>
<junk-tag>
<tag1>BASIC</tag1>
<tag2>BASIC</tag2>
</junk-tag>
</web-app>
例如。假设我在下面搜索一个Servlet名称为"BBB"的Servlet。如果找到了,那么我检查它的<param-name>
值为XXX的<B>
标记是否不存在,然后添加它,使o/p如下所示。如果"BBB"<servlet-name>
具有<B>
标签,并且<param-name>
值XXX已经存在,那么我什么都不做。
OUTPUT.XML
<web-app metadata-complete="true">
<servlet>
<servlet-name>AAA</servlet-name>
<servlet-class>com.AAA</servlet-class>
<B>
<param-name>port</param-name>
<param-value>8802</param-value>
</B>
<B>
<param-name>connectors-xml</param-name>
<param-value/>
</B>
<B>
<param-name>webservices-xml</param-name>
<param-value/>
</B>
<B>
<param-name>exposure-server</param-name>
<param-value/>
</B>
<some-tag>1</some-tag>
</servlet>
<servlet>
<servlet-name>BBB</servlet-name>
<servlet-class>com.BBB</servlet-class>
<B>
<param-name>port</param-name>
<param-value>8802</param-value>
</B>
<B>
<param-name>connectors-xml</param-name>
<param-value/>
</B>
<B>
<param-name>webservices-xml</param-name>
<param-value/>
</B>
<B>
<param-name>exposure-server</param-name>
<param-value/>
</B>
<B>NEW</B>
<some-tag>2</some-tag>
</servlet>
<C>
<D>
</D
</C>
<junk-tag>
<tag1>BASIC</tag1>
<tag2>BASIC</tag2>
</junk-tag>
</web-app>
我尝试过编写XSLT,但不知何故遇到了BUGS和语法问题
<xsl:template match="web-app/servlet[servlet-name='BBB/B']">
<xsl:copy-of select="."/>
<xsl:choose>
<xsl:when test="not(/web-app/servlet[servlet-name='BBB']/B[param-name='XXX'])">
<B>NEW</B>
</xsl:when>
</xsl:choose>
</xsl:template>
有什么指导吗?我是XSLT的新手,并尝试通过谷歌搜索它自己。
您想要的表达式只是not(B[param-name='XXX'])
,因为此时您已经位于相关的servlet
上,因此此表达式将与之相关。此外,您当前的代码将复制现有的servlet
,并在它之后添加<B>NEW</B>
,而实际上您希望它作为子代码。
所以你可以这样做。。。。
<xsl:template match="web-app/servlet[servlet-name='BBB']">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:if test="not(B[param-name='XXX'])">
<B>NEW</B>
</xsl:if>
</xsl:copy>
</xsl:template>
或者更好的是,将检查放在模板匹配本身中
<xsl:template match="web-app/servlet[servlet-name='BBB'][not(B[param-name='XXX'])]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<B>NEW</B>
</xsl:copy>
</xsl:template>
(两者都假设您也在使用身份模板)
但是,这会在<some-tag>2</some-tag>
之后添加您的新标签,这可能不是您想要的。
如果要将其放置在最后一个B
元素之后,则应更改模板以匹配最后一个B
元素。
<xsl:template match="web-app/servlet[servlet-name='BBB'][not(B[param-name='XXX'])]/B[last()]">
<xsl:copy-of select="." />
<B>NEW</B>
</xsl:template>
尝试此XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="web-app/servlet[servlet-name='BBB'][not(B[param-name='XXX'])]/B[last()]">
<xsl:copy-of select="." />
<B>NEW</B>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>