2011-06-16 54 views
4

我已經開始學習XSLT剛剛並拿出scenario.The源和目標結構完全相同的這個我能夠與下面的代碼來完成:問題與COPY應用模板XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="node()|@*"> 
     <xsl:copy><xsl:apply-templates select="node()|@*" /></xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

但是我的要求是隻有滿足其中一個條件才能創建目標節點。

實施例如果

VNum當量999

源和目標應該是這樣的:

<POExt> 
    <SD>01</SD> 
    <PODet> 
     <PNum schemeAgencyID="TEST">12345678</PNum> 
     <VNum>999</VNum> 
    </PODet> 
    <PODet> 
     <PNum schemeAgencyID="">45654654</PNum> 
     <VNum>001</VNum> 
    </PODet> 
</POExt> 

目標

<POExt> 
    <SD>01</SD> 
    <PODet> 
     <PNum schemeAgencyID="TEST">12345678</PNum> 
     <VNum>999</VNum> 
    </PODet> 
</POExt> 

<PODet>重複每次它符合VNum標準,如果沒有<PODet>的滿足它是確定的標準,讓

<POExt> 
    <SD>01</SD> 
</POExt> 

要做到這一點使用複製和應用模板,任何幫助將是非常讚賞。

謝謝..

回答

3

當與身份規則你需要重寫通過匹配模板的內容合作。

對於您的情況,您不希望複製不符合特定條件的PODet元素。根據負面的邏輯,你只需'閉嘴'不符合你的條件的節點。例如:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="PODet[not(VNum/text()=999)]"/> 

</xsl:stylesheet> 

如果您VNum是可變的,說對輸入參數的變換,在XSLT 2.0,你可以簡單地做:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output indent="yes"/> 

    <xsl:param name="VNum" select="999"/> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="PODet[not(VNum/text()=$VNum)]"/> 

</xsl:stylesheet> 

在XSLT 1.0變量沒有在模板匹配允許模式,以便您必須在模板內包含條件檢查。例如,您可以應用模板只有符合條件的元素:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:param name="VNum" select="999"/> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="PODet"> 
     <xsl:apply-templates select="VNum[text()=$VNum]"/> 
    </xsl:template> 

    <xsl:template match="VNum"> 
     <xsl:copy-of select=".."/> 
    </xsl:template> 

</xsl:stylesheet> 
+0

感謝EMPO,我的問題是現在解決.. – NewtoXSLT 2011-06-16 07:40:53

+1

歡迎您。請接受答案(如果你喜歡,請接受),以便其他人可以依靠這個答案。這就是SO的工作方式,並向回答者表示感謝。 – 2011-06-16 08:23:30

+0

+1爲一個很好的答案。 – 2011-06-16 12:49:48