2015-11-02 75 views
1

我想使用XSLT 1.0執行xml到xml轉換。如果「Removeornot」值不是「1」,我需要從XML中刪除完整節點。XSLT - 如果grandchild元素包含特定文本,則刪除完整父節點

我已經嘗試過創建模板:

<xsl:template match="//Node[not(Grandchild0[not(Grand3child[not(Grand4child[not(Grand5child[not(Grand6child[not(Removeornot = 1)])])])])])]"/> 

該模板工作正常,如果XML有較少的水平,但我不能adobt到我的解決方案。所以也許有人可以幫忙。

源XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Family> 
    <Node> 
     <Child0>AAA</Child0> 
     <Child1>BBB</Child1> 
     <Child2> 
      <Grandchild0> 
       <Grand2child>DDD</Grand2child> 
       <Grand3child> 
        <Grand4child> 
         <Grand5child> 
          <Grand6child> 
           <Removeornot>1</Removeornot> 
          </Grand6child> 
          <Grand6child1>QQQ </Grand6child1> 
         </Grand5child> 
         <Grand5child1>ZZZ </Grand5child1> 
        </Grand4child> 
       </Grand3child> 
       <Grand2child2>EEE</Grand2child2> 
      </Grandchild0> 
      <Grandchild2>FFF</Grandchild2> 
      <Grandchild3>GGG</Grandchild3> 
      <Grandchild4>HHH</Grandchild4> 
      <Grandchild5>IIII</Grandchild5> 
     </Child2> 
    </Node> 
    <Node> 
     <Child0>AAA</Child0> 
     <Child1>BBB</Child1> 
     <Child2> 
      <Grandchild0> 
       <Grand2child>DDD</Grand2child> 
       <Grand3child> 
        <Grand4child> 
         <Grand5child> 
          <Grand6child> 
           <Removeornot>YES</Removeornot> 
          </Grand6child> 
          <Grand6child1>QQQ </Grand6child1> 
         </Grand5child> 
         <Grand5child1>ZZZ </Grand5child1> 
        </Grand4child> 
       </Grand3child> 
       <Grand2child2>EEE</Grand2child2> 
      </Grandchild0> 
      <Grandchild2>FFF</Grandchild2> 
      <Grandchild3>GGG</Grandchild3> 
      <Grandchild4>HHH</Grandchild4> 
      <Grandchild5>IIII</Grandchild5> 
     </Child2> 
    </Node> 
    <Node> 
     <Child0>AAA</Child0> 
     <Child1>BBB</Child1> 
     <Child2> 
      <Grandchild0> 
       <Grand2child>DDD</Grand2child> 
       <Grand3child> 
        <Grand4child> 
         <Grand5child> 
          <Grand6child> 
           <Removeornot>NO</Removeornot> 
          </Grand6child> 
          <Grand6child1>QQQ </Grand6child1> 
         </Grand5child> 
         <Grand5child1>ZZZ </Grand5child1> 
        </Grand4child> 
       </Grand3child> 
       <Grand2child2>EEE</Grand2child2> 
      </Grandchild0> 
      <Grandchild2>FFF</Grandchild2> 
      <Grandchild3>GGG</Grandchild3> 
      <Grandchild4>HHH</Grandchild4> 
      <Grandchild5>IIII</Grandchild5> 
     </Child2> 
    </Node> 
</Family> 

這只是XSLT打印 「Removeornot」 值。完成此任務的其他方法是將此值用作變量,但正如我所瞭解的,XSLT中的變量完全不可變,並且我無法在每個循環外使用它們。任何想法如果值內容錯誤,我該如何使用這個值去除節點?

XSLT來源:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="v2"> 
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:template match="/"> 
     <xsl:for-each select="Family/Node"> 
     <xsl:call-template name="tests"></xsl:call-template> 
     <!-- Is it possible to get variable value here to understand if node shloud be deleted? 
      <xsl:if test="$tester = 1"> 
      <xsl:call-template name="copyit"></xsl:call-template> 
       </xsl:if> --> 
     </xsl:for-each> 
</xsl:template> 

<xsl:template name="tests"> 
<!--  <xsl:for-each select="Family/Node"> --> 
    <xsl:for-each select="Child2/Grandchild0"> 
     <xsl:for-each select="Grand3child/Grand4child"> 
      <xsl:for-each select="Grand5child/Grand6child"> 
       <xsl:value-of select="Removeornot"></xsl:value-of> 
        <!-- <xsl:variable name="tester" select="Removeornot" ></xsl:variable>--> 
       </xsl:for-each> 
      </xsl:for-each> 
      </xsl:for-each> 
<!--  </xsl:for-each> --> 
</xsl:template> 

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

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

</xsl:stylesheet> 

預期結果:

<?xml version="1.0" encoding="UTF-8"?> 
<Family> 
    <Node> 
     <Child0>AAA</Child0> 
     <Child1>BBB</Child1> 
     <Child2> 
      <Grandchild0> 
       <Grand2child>DDD</Grand2child> 
       <Grand3child> 
        <Grand4child> 
         <Grand5child> 
          <Grand6child> 
           <Removeornot>1</Removeornot> 
          </Grand6child> 
          <Grand6child1>QQQ </Grand6child1> 
         </Grand5child> 
         <Grand5child1>ZZZ </Grand5child1> 
        </Grand4child> 
       </Grand3child> 
       <Grand2child2>EEE</Grand2child2> 
      </Grandchild0> 
      <Grandchild2>FFF</Grandchild2> 
      <Grandchild3>GGG</Grandchild3> 
      <Grandchild4>HHH</Grandchild4> 
      <Grandchild5>IIII</Grandchild5> 
     </Child2> 
    </Node> 
</Family> 

我是新太XSLT,每一個幫助表示讚賞。

回答

0

如果「Removeornot」值不是「1」,我需要從XML中刪除完整節點。

這將是

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 

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

    <xsl:template match="Node[not(.//Removeornot = 1)]" /> 
</xsl:transform> 
  1. 身份模板拷貝的每一個節點,除非更具體的模板匹配。
  2. Node[not(.//Removeornot = 1)]的另一個模板更具體 - 它並不輸出任何與此處匹配的節點,它實際上從輸入中移除了這些節點。
+0

謝謝!它適用於這個例子,但是如何匹配特定的// Removeornot?例如:如果Child1 /../ Removeornot也有sutch元素? – archijs

+0

你的評論已經包含了答案。給它五分鐘,它會來找你。 – Tomalak

+0

@Artūrs所以,你知道嗎? – Tomalak

相關問題