2011-01-25 24 views
5

喜 我有一個網站地圖的XML文檔看起來像這樣XSLT複製的無子女

<pagenode title="home" url="~/" fornavbar="true"> 
<pagenode title="admin" url="~/admin" fornavbar="false"> 
    <pagenode title="users" url="~/admin/users" fornavbar="false"/> 
    <pagenode title="events" url="~/admin/events" fornavbar="true"/> 
</pagenode> 
<pagenode title="catalog" url="~/catalog" fornavbar="true"/> 
<pagenode title="contact us" url="~/contactus" fornavbar="false"/> 
</pagenode> 

現在我想檢索導航欄的XML文檔,其中包括所有的pagenodes有fornavbar =真正。如何才能做到這一點?

我是能夠得到到目前爲止最接近的是這樣的:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="pagenode[@fornavbar='true']"> 
    <xsl:copy-of select="."/> 
</xsl:template> 
</xsl:stylesheet> 

這個問題,包括匹配的導航欄的任何事情所有的孩子

我只希望所有的屬性複製並不是所有的孩子

但如果我嘗試

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="pagenode[@fornavbar='true']"> 
    <pagenode title="{@title}" url="{@url}"/> 
    <xsl:apply-templates/> 
</xsl:template> 
</xsl:stylesheet> 

然後,我有2個問題

  1. 我可能分別鍵入出每個屬性,和我有相當每頁數和theyre容易最終
  2. 改變它失去層次。一切都變得平坦

我會感謝所有和任何幫助。

謝謝!

編輯:樣本輸出ID喜歡看

<pagenode title="home" url="~/" fornavbar="true"> 
<pagenode title="events" url="~/admin/events" fornavbar="true"/> 
<pagenode title="catalog" url="~/catalog" fornavbar="true"/> 
</pagenode> 
+0

好問題,+1。請參閱我的答案,以獲取完整而非常短的解決方案,充分利用最基本的XSLT設計模式。 :) – 2011-01-25 14:32:42

回答

2

您可以通過使用xsl:foreach select="@*" 這樣你不必用手屬性複製節點的屬性進行迭代。如果您在yor pagenode元素內部調用xsl:apply-templates ,則應該獲得所需的結果。

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="pagenode[@fornavbar='true']"> 
     <pagenode> 
      <xsl:for-each select="@*"> 
       <xsl:attribute name="{name(.)}"><xsl:value-of select="."/></xsl:attribute> 
      </xsl:for-each> 
      <xsl:apply-templates/> 
     </pagenode> 
    </xsl:template> 
</xsl:stylesheet> 

使得

<?xml version="1.0"?> 
<pagenode title="home" url="~/" fornavbar="true"> 
    <pagenode title="events" url="~/admin/events" fornavbar="true"/> 
    <pagenode title="catalog" url="~/catalog" fornavbar="true"/> 
</pagenode> 
+1

``更簡潔 – 2011-01-25 17:16:49

+0

謝謝!它正是我需要的!你太棒了! – 2011-01-26 10:55:11

1

XSLT應該是這樣的:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="pagenode[@fornavbar='true']"> 
    <pagenode> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates/> 
    </pagenode> 
    </xsl:template> 
</xsl:stylesheet> 
+0

必須從我的測試剩菜。 – akond 2011-01-25 17:18:34

3

這可能是最短的,最純潔的XSLT解決方案:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="*[@fornavbar = 'false']"> 
    <xsl:apply-templates/> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔被應用於這種轉變:

<pagenode title="home" url="~/" fornavbar="true"> 
    <pagenode title="admin" url="~/admin" fornavbar="false"> 
     <pagenode title="users" url="~/admin/users" fornavbar="false"/> 
     <pagenode title="events" url="~/admin/events" fornavbar="true"/> 
    </pagenode> 
    <pagenode title="catalog" url="~/catalog" fornavbar="true"/> 
    <pagenode title="contact us" url="~/contactus" fornavbar="false"/> 
</pagenode> 

有用,正確的結果產生:

<pagenode title="home" url="~/" fornavbar="true"> 
    <pagenode title="events" url="~/admin/events" fornavbar="true"/> 
    <pagenode title="catalog" url="~/catalog" fornavbar="true"/> 
</pagenode> 

說明:

  1. 身份規則(模板)「按原樣」複製每個節點。使用identity rule並重寫它是最基本的XSLT設計模式。

  2. 有重寫身份規則一個模板 - 對於其fornavbar屬性"false"元素。這裏指定的動作是在當前元素的子元素上應用模板。