2016-05-25 20 views
2

は、私は次のXMLがあるとしXSLT Change要素の順序

<?xml version="1.0" encoding="UTF-8"?> 
<Test xmlns="http://someorg.org"> 
    <name> 
    <use value="usual"/> 
    <given value="given"/> 
    <family value="family"/>  
    <suffix value="MSc"/> 
    </name> 
</Test> 

を私が試しました次のようにxsl:paply.templateを使用しますが、apply-templatesはすべての子ノードにテンプレートを適用するため、順序が変更されたノードも出力され、ノードにテンプレートを適用できないようにする方法がわかりませんその注文はすでに変更されています。

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:f="http://someorg.org" 
xmlns="http://someorg.org" 
exclude-result-prefixes="f xsl"> 

    <xsl:template match="*"> 
     <xsl:element name="{local-name(.)}"> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:element> 
    </xsl:template> 


    <xsl:template match="@*"> 
     <xsl:attribute name="{local-name(.)}"> 
      <xsl:value-of select="."/> 
     </xsl:attribute> 
    </xsl:template> 

    <xsl:template match="/"> 

     <xsl:apply-templates/> 
    </xsl:template> 

    <xsl:template match = "f:name"> 
    <xsl:apply-templates select = "f:given"/> 
    <xsl:apply-templates select = "f:family"/> 
    <xsl:apply-templates/>   
    </xsl:template>  
</xsl:stylesheet> 

答えて

3

すなわち

<xsl:template match = "f:name"> 
    <xsl:copy> 
    <xsl:apply-templates select="f:use"/> 
    <xsl:apply-templates select="f:given"/> 
    <xsl:apply-templates select="f:family"/> 
    <xsl:apply-templates select="f:suffix"/> 
    </xsl:copy>   
</xsl:template>  

XSLT 2.0で、ここで

<xsl:template match = "f:name"> 
    <xsl:copy> 
    <xsl:apply-templates select="f:use, f:given, f:family, f:suffix"/> 
    </xsl:copy>   
</xsl:template> 
+0

感謝。ですから、私はすべての要素テンプレートに、必要な順番で適用する必要がありますか?最初の2つの要素だけを注文するように適用テンプレートを伝える方法はありませんか、残りは順序なしでそのまま残りますか?私の場合、この例ではいくつかのテンプレートしか持っていませんが、何十もの要素があり、最初の要素と2番目の要素の位置だけを交換してそのまま残りたいとしましょう。この場合でも、各要素ごとにapply-templatesを数十回書くのですか? – Enigma

+0

あなたは、 (self :: f:use | self :: f:given)] "/>'これは、 'use'や' given'以外の子要素をすべて処理します。 XSLT 2.0では 'except'を使用することができます。 (f:use、f:given) "/>' –

+0

ええ、私はこれらの行に何かを意味しました、ありがとう! – Enigma

1

を書くことが容易である、あなたが欲しいためにapply-templatesを持っている必要があります順序を変更するには、aはジェネリックと短い、完全なXSLT 1.0ソリューション

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

<xsl:variable name="vOrdered" select="'|use|given|family|suffix|'"/> 

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

    <xsl:template match="my:name"> 
    <xsl:copy> 
     <xsl:apply-templates select="*"> 
     <xsl:sort select="substring-before($vOrdered, concat('|',name(),'|'))"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

この変換が提供されるXML文書に適用されます。

<Test xmlns="http://someorg.org"> 
    <name> 
     <use value="usual"/> 
     <family value="family"/> 
     <given value="given"/> 
     <suffix value="MSc"/> 
    </name> 
</Test> 

指名手配、正しい結果、が生成されます

<Test xmlns="http://someorg.org"> 
    <name> 
     <use value="usual"/> 
     <given value="given"/> 
     <family value="family"/> 
     <suffix value="MSc"/> 
    </name> 
</Test> 

注意ください:

  1. つだけ<xsl:apply-templates>命令が使用され、私たちはf:name要素の子の新しい順序を指定したい場合は、テンプレートのコードは変更されません。

  2. 要素の順序は、現在のXSLTスタイルシートにdocument()などの標準関数を使用して動的に取得し、独立した "構成ファイル"として使用できる別個のXML文書で指定できます。新しい並べ替えが必要なときに、変換を変更する必要はありません。設定ファイルだけを変更する必要があります。

+1

鮮やかな解決策、私が探していたもの。 'name'に既存の属性を追加して保存したいのであれば、これはどのように達成できますか?内側の 'xsl:apply-templates'要素で' select = "*" 'を' select = "* | @ *" 'に変更するだけですか? – Markus

+0

ここに答えてください: 'xsl:apply-templates select =" * * ">の直前に' xsl:apply-templates select = "@ *" /> :copy'要素です。 – Markus

+0

@Markus、はい、これは私がやることです - 明確で短い。 –

関連する問題