2011-05-12 36 views
4

我有XML文件,我想將它複製,但我想過濾一些不需要的元素和屬性,例如以下是原始文件:如何使用XSLT從XML文件中刪除不需要的元素和屬性

<root> 
<e1 att="test1" att2="test2"> Value</e1> 
<e2 att="test1" att2="test2"> Value 2 <inner class='i'>inner</inner></e2> 
<e3 att="test1" att2="test2"> Value 3</e3> 

</root> 

過濾(E3元件和ATT2屬性已被去除)之後:

<root> 
<e1 att="test1" > Value</e1> 
<e2 att="test1" > Value 2 <inner class='i'>inner</inner></e2> 
</root> 

注:

  • 我更喜歡使用(的for-each元素而不是應用模板如果可能的話)
  • 我有一些問題的xsl:元素的xsl:屬性,因爲我無法寫入當前節點名稱

感謝

+1

你爲什麼喜歡用'for-each'而不是'apply-templates'? – 2011-05-12 23:53:16

+1

@lwburk - 我認爲「我對xsl:element和xsl:attribute有一些問題......」指向一些更深層根源的問題。 – 2011-05-13 00:09:35

+1

目前還不清楚您是在尋找一個通用解決方案(未知元素名稱)還是特定的解決方案(過濾器'e3')。我提供的答案在前一種情況下將對您有所幫助,即使它很容易適應特定情況。 – 2011-05-13 05:46:29

回答

8

我知道你更願意使用for-each,但爲什麼不使用身份轉換,然後用你不想保留的模板覆蓋該模板?

這個樣式表:

<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="e3|@att2"/> 

</xsl:stylesheet> 

生產:

<root> 
    <e1 att="test1"> Value</e1> 
    <e2 att="test1"> Value 2 <inner class="i">inner</inner> 
    </e2> 
</root> 
+0

@DevNull:如果最後一個節點與'e3'不同,這將不起作用。我已經概括了你的答案。 – 2011-05-13 05:41:09

+1

@empo - 這是真的,但我沒有看到原始文章中有關刪除最後一個節點的任何內容,無論名稱是什麼。原來的文章指出'e3'和'att2'已被刪除。遵循你的邏輯,我也可以假設OP正試圖刪除名稱以「3」結尾的所有元素。 – 2011-05-13 07:24:56

+0

@DevNull:是的,誰知道,除非這個人直接插入:D! – 2011-05-13 07:42:57

1

由於@DevNull表明您使用的身份轉換爲更容易和更簡潔。總之,這裏是for-each並沒有apply-templates你要求一個可能的解決方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:template match="/root"> 
    <root> 
    <xsl:for-each select="child::node()"> 
    <xsl:choose> 
     <xsl:when test="position()=last()-1"/> 
     <xsl:otherwise> 
     <xsl:copy> 
     <xsl:copy-of select="@att"/> 
     <xsl:copy-of select="child::node()"/> 
     </xsl:copy> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:for-each> 
    </root> 
</xsl:template> 


注意有關使用身份變換

如果情況真的是什麼樣子,我意思是元素的未知名稱,@DevNull將不起作用,並且您需要更像此類的東西:

<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="root/child::node()[position()=last()]|@att2"/> 

</xsl:stylesheet> 

即使使用最後一個元素e4e1000,此解決方案也可以工作。

+0

非常感謝你,實際上我想刪除元素「e3」而不是最後一個元素,對於不清楚的問題抱歉。你的解決方案是完美的兩種方式..但我選擇@DevNull解決方案,因爲它適合我的情況。再次,謝謝你 。 – Abdullah 2011-05-13 11:02:25

相關問題