我的输入XML如下。基本上,XML有各种<servlet-name>
标签。我的要求是应用一个XSLT转换,它浏览<B>
标签并查看是否存在具有指定名称的特定servlet。如果它存在,那么我需要看到具有<param-name>
的特定servlet下的标记<param-name>
不存在。如果搜索下的特定<B>NEW</B>
标记不存在,那么我会添加标记<B>
以及该特定servlet的其他<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>
标记,否则我不会执行任何操作。< / p>
INPUT XML
<B>
例如。假设我在下面搜索Servlet名称为“BBB”的Servlet。如果找到,那么我检查其<param-name>
标签<servlet-name>
值XXX不存在,然后我添加它,以便o / p如下所示。如果“BBB”<B>
的{{1}}标记<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很有兴趣,并尝试使用谷歌搜索。
答案 0 :(得分:1)
您想要的表达式仅为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>
(这两个假设您也使用identity 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>