2015-09-04 55 views
0

我有XML項目如下基於匹配的XML元素:添加使用XSL

<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> 

實現這一目標,但它是什麼做的是完全刪除信息塊和添加線

需要有關正確執行此操作的建議。

回答

2

問題出在您的模板中,您正在創建一個新元素,但您告訴XSLT也複製現有的component節點及其子節點。當您找到匹配的節點時,您實際上是在說,請改爲創建一個新節點。

你需要做的,是在xsl:if條件移動到模板匹配,而不是添加代碼複製現有節點,像這樣

<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:elementxsl: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的轉換中複製所有其他現有節點。

+0

非常感謝蒂姆。它正在做我想做的事情。 –