2011-01-25 11 views
5

ハイテク のない私は今、私はfornavbar =を持っているすべてのpagenodesを含んナビゲーションバー用の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文書を持っています本当。どのようにこれを行うことができますか?

私は、これまでに取得することができた最も近いが、これだった:これに伴う問題は、それは私が唯一のすべての属性をコピーするナビゲーションバー

としてマッチしたもののすべての子を含んで

<?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. を持っている、と私はかなりのページあたりの数と、それは階層を失い、最終的
  2. 変更すること聞きしたい傾向があります。すべてが平らになります。

私はこの問題に関するすべての助けに感謝します。

ありがとうございました!

EDIT: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デザインパターンを完全に活用する、完全でありながら非常に短いソリューションについては、私の答えをご覧ください。 :) –

答えて

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

''ははるかに簡潔です –

+0

100万に感謝!それは正確に私が必要なものを動作させる!あなたの優秀な! –

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

+0

+1最も簡単な補正のため。 –

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デザインパターンです。 fornavbar属性"false"のある要素について -

  2. はアイデンティティルールをオーバーライドする単一のテンプレートがあります。ここで指定されたアクションは、現在の要素の子にテンプレートを適用することです。

+1

+1良い答え。セマンティックと1つの唯一のルール解決の逆の論理として、私は '* [not(self :: pagenode/@ fornavbar = 'true')]' –

+0

@Alejandro:ありがとう。どういう意味ですか? –

+0

私はバイパスルールが '@ fornavbar'属性を持つ要素を' 'false''文字列値とマッチさせるので、アイデンティティ規則は' '@ fornavbar'属性を持たない要素**に' 'false 'pagenode'要素の代わりに' string value '** **' true 'の文字列値を持つ '@ fornavbar'属性を持つ**のみです。 –