我有xml条目如下:
<employee>
<component name="address">
<property name="city" value="Bangalore">
<property name="state" value="Karnataka">
<component/>
<component name="info">
<property name="name" value="Alok"></property>
<property name="age" value="25"></property>
</component>
</employee>
因此,对于在信息领域中的输入,我想添加一个位置为工程师的元素,如下所示:
<property name="position" value ="engineer"></property>
我试图通过
来实现这一目标<xsl:template match="/employee/component[@name='info']">
<xsl:if test="not(property[@name='position'])">
<xsl:element name="property">
<xsl:attribute name="position">position</xsl:attribute>
<xsl:attribute name="value">engineer</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:template>
但它正在做的是完全删除信息块并添加行
需要有关正确实施方法的建议。
答案 0 :(得分:2)
问题在于您的模板,您正在创建一个新元素,但您告诉XSLT还要复制现有的component
节点及其子节点。当您找到匹配的component
节点时,您实际上是在说,而是创建一个新节点。
您需要做的是添加代码以复制现有节点,如此
<xsl:template match="/employee/component[@name='info']">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:if test="not(property[@name='position'])">
<xsl:element name="property">
<xsl:attribute name="position">position</xsl:attribute>
<xsl:attribute name="value">engineer</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:copy>
</xsl:template>
这可以通过将xsl:if
中的条件移动到模板匹配来简化。此外,此处无需使用xsl:element
和xsl:attribute
,只需直接写出新元素。
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="/employee/component[@name='info'][not(property[@name='position'])]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<property position="position" name="engineer" />
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意在转换中使用Identity Template来复制所有其他现有节点。