2016-09-15 8 views
0

こんにちは私はhtmlページに変換する必要があるxmlファイルを持っています。以下のように、このファイルの構造である(簡体字):XMLソースの順序に則ったXSLTテンプレートを適用

<top> 
<element> 
    <option id="SectionA">  
     <content id="ContentA1"></content> 
     <content id="ContentA2"></content> 
     <option id="ContentA3"> 
      <content id="ContentA31"></content> 
      <content id="ContentA32"></content> 
      <option id="ContentA33"></option> 
     </option> 
     <content id="ContentA4"></content> 
    </option> 
    <option id="SectionB"> 
     <content id="ContentA1"></content> 
     <content id="ContentA2"></content> 
    </option>  
    <option id="SectionC"> 
     <content id="ContentA1"></content> 
     <content id="ContentA2"></content>  
    </option>  
</element> 

は私のXSLファイルは(簡体字)のようになります。

<?xml version="1.0" encoding="utf-8"?> 

<xsl:template match="/">  
    <!-- Output html --> 
    <xsl:apply-templates select="top/elements"/> 
</xsl:template> 

<xsl:template match="top/elements"> 
    <xsl:apply-templates select="option" /> 
</xsl:template> 


<xsl:template match="option">  
    <!-- Output html --> 
    <xsl:if test="content">    
     <xsl:apply-templates select="content"/> 
    </xsl:if> 
    <xsl:if test="option"> 
     <xsl:apply-templates select="option"/> 
    </xsl:if>      
</xsl:template> 

<xsl:template match="content"> 
    <!-- Output html --> 
</xsl:template> 

変換は動作しますが、今私がする必要があります要素の順序が尊重されるような方法で出力を強制します。私が知る限り、テンプレートを使用すると、XSLはそのために定義されたすべての要素を反復処理します。したがって、最初に<xsl:apply-templates select="content" />のoption-templateはすべてのcontent-elementを出力し、その後はすべてのoption-element(サブレベルにある)を出力します。問題は、XML文書と同じ順序を維持する必要があることです。だから、sectionAのための出力は次のようになります。代わりに私の解決策の出力の

  • ContentA1
  • ContentA2
  • OptionA3
  • ContentA4

  • ContentA1
  • ContentA2
  • ContentA4
  • OptionA3

だから、最初にすべてのContent-要素とオプションの要素よりも処理します。 出力のxmlに含まれる注文を強制的に強制することはできますか?

+0

テンプレート 'match =" option "'を ':<! - Output html - >'に書き直すことはできますか?いいえ、Ifs!明示的な要素の呼び出しはありません。代わりに、空の ''が作業をするようにしてください(ドキュメントオーダーは維持されます)。 – uL1

答えて

1

XSLTプロセッサは、デフォルトでは、文書の順で入力XMLを介して動作します。

あなたがする必要があるのは<xsl:apply-templates />です。

<html> 
    <section> 
     <div> 
     <span>SectionA</span> 
     <p> 
      <span>ContentA1</span> 
     </p> 
     <p> 
      <span>ContentA2</span> 
     </p> 
     <div> 
      <span>ContentA3</span> 
      <p> 
       <span>ContentA31</span> 
      </p> 
      <p> 
       <span>ContentA32</span> 
      </p> 
      <div> 
       <span>ContentA33</span> 
      </div> 
     </div> 
     <p> 
      <span>ContentA4</span> 
     </p> 
     </div> 
     <div> 
     <span>SectionB</span> 
     <p> 
      <span>ContentA1</span> 
     </p> 
     <p> 
      <span>ContentA2</span> 
     </p> 
     </div> 
     <div> 
     <span>SectionC</span> 
     <p> 
      <span>ContentA1</span> 
     </p> 
     <p> 
      <span>ContentA2</span> 
     </p> 
     </div> 
    </section> 
</html> 

このような構造になり

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" /> 

    <xsl:template match="/"> 
     <html> 
      <xsl:apply-templates select="top/element" /> 
     </html> 
    </xsl:template> 

    <xsl:template match="element"> 
     <section> 
      <xsl:apply-templates /> 
     </section> 
    </xsl:template> 

    <xsl:template match="option"> 
     <div> 
      <span><xsl:value-of select="@id" /></span> 
      <xsl:apply-templates /> 
     </div> 
    </xsl:template> 

    <xsl:template match="content"> 
     <p> 
      <span><xsl:value-of select="@id" /></span> 
      <xsl:apply-templates /> 
     </p> 
    </xsl:template> 
</xsl:stylesheet> 

次のような単純な変換が <p><div><content><section><element><option>をマッピングし、私が何を意味するか表示するには

<xsl:if test="content">    
    <xsl:apply-templates select="content"/> 
</xsl:if> 

は実際には必要ありません。何contentノードが存在しない場合は、<xsl:apply-templates>は上で動作するように何も持っていないので、これは同等のようになります。

<xsl:apply-templates select="content"/> 

を、あなたが彼らの元の順序で処理されるすべての子どもが欲しいから、それを行うには最も簡単です:

<xsl:apply-templates /> 

か、あなたはより具体的にしたい場合は、あなたが労働組合を使用することができます。

<xsl:apply-templates select="content|option"/> 

これはまた、入力順序を維持するであろう。

+0

thx。それは今働いている。これは私が探していたものです。 – Stephan

1

テストは不要です。ノードが存在しない場合、それに一致するテンプレートは実行されません。代わりに:

<xsl:template match="option">  
    <!-- Output html --> 
    <xsl:if test="content">    
     <xsl:apply-templates select="content"/> 
    </xsl:if> 
    <xsl:if test="option"> 
     <xsl:apply-templates select="option"/> 
    </xsl:if>      
</xsl:template> 

あなたは、単に行うことができます。

<xsl:template match="option">  
    <!-- Output html --> 
    <xsl:apply-templates select="content | option"/>   
</xsl:template> 
+0

ご返信いただきありがとうございます。 – Stephan

関連する問題