2017-02-10 14 views
0

これまで編集してきましたが、私はこれほど長い間、一見簡単な解決法を見つけることに失敗しています。動的に作成された子と兄弟の子を処理する

要素(およびその兄弟)には、HTMLテーブルに表示するさまざまな(動的な)結果が各CDファイルペアごとに1つずつあります。当初、私は各ループを避けることができると思っていましたが(とにかく同じ結果を返すようです)、私は子供たちを参照するにはより良い方法が必要です。下のソースは、私が働いているのと同様の構造です。

たとえば、「cd」や「file」には価格などの要素が多く、情報がないものもあります。

XML

<?xml version="1.0" encoding="UTF-8"?> 
    <?xml-stylesheet type="text/xsl" href="cdcatalog.test2.xsl"?> 
    <catalog> 
     <rock> 
     <album> 
      <cd> 
      <title>Empire Burlesque</title> 
      <artist>Bob Dylan</artist> 
      </cd> 
      <file> 
      <store>Apple</store> 
      <size>3823</size> 
      </file> 
     </album> 
     <album> 
      <cd> 
      <title>Hide your heart</title> 
      <artist>Bonnie Tyler</artist> 
      </cd> 
      <file> 
      <store>Amazon</store> 
      <size>2123</size> 
      </file> 
     </album> 
     </rock> 
    </catalog> 

XSLT

<?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="/"> 
    <html> 
    <body> 
     <h2>My CD Collection</h2> 
     <table border="1"> 
     <tr bgcolor="#cccccc"> 
      <th style="text-align:left">Title</th> 
      <th style="text-align:left">Artist</th> 
      <th style="text-align:left">Store</th> 
      <th style="text-align:left">Size</th> 
     </tr> 
     <xsl:apply-templates/> 
     </table> 
    </body> 
    </html> 
    </xsl:template> 

    <xsl:template match="album"> 
     <tr> 
     <xsl:apply-templates select="cd"/> 
     <xsl:apply-templates select="file"/> 
     </tr> 
    </xsl:template> 

    <xsl:template match="cd"> 
     <td> 
     <xsl:value-of select="."/> 
     </td> 
    </xsl:template> 

    <xsl:template match="file"> 
     <td> 
     <xsl:value-of select="."/> 
     </td> 
    </xsl:template> 

    </xsl:stylesheet> 

結果今

<table border="1"> 
     <tbody> 
     <tr bgcolor="#cccccc"> 
      <th style="text-align:left">Title</th> 
      <th style="text-align:left">Artist</th> 
      <th style="text-align:left">Store</th> 
      <th style="text-align:left">Size</th> 
     </tr> 
     <tr> 
      <td> 
      Empire Burlesque 
      Bob Dylan 
      </td> 
      <td> 
       Apple 
       3823 
      </td> 
     </tr> 
     <tr> 
      <td> 
      Hide your heart 
      Bonnie Tyler 
      </td> 
      <td> 
      Amazon 
      2123 
      </td> 
     </tr> 
     </tbody> 
    </table> 

Result View

、私は何が起こっているかを見ると思います。私の解釈からは、XSLTファイルの "cd"と "file"テンプレートの下で、select="."<td>のすべての子を返しています。それぞれが<td>を持つ方法が必要です。私は、 "cd"と "file"テンプレートの中のfor-eachと同様に、それぞれの "cd"と "file"のためのコールテンプレートのようなものを試しました。 <th>要素も動的に構築する必要があることに注意してください。テスト用に手動で作成されているからです。助言がありますか?

+0

"動的に"より良い定義が必要です。たとえば、テキスト値を持つすべての葉ノードの列が必要だと言うことができます。しかし、どの要素が行を生成するかをハードコーディングしないようにする方法はありません。 –

+0

私は静的ではなく動的に言及しています。 [number of]列は、API呼び出しから返される内容に応じて動的に作成されます。 0個以上の子、この場合は葉があります。葉にはテキストが含まれていてもいなくてもかまいません。異なるノード名が異なる順番で表示されます(それぞれテーブル内に列があります)。 – MasterWill

+0

何が変わるかは言うまでもありません。あなたは私たちにそれが出力テーブルのための構造体を作成するために使用できるように、私たちに教えてください。制約がない場合、タスクは不可能です。 –

答えて

1

予想される出力がどのように見えているのか、入力ファイルのどの部分が可変であるのかが明確ではないので、次のようにしたいと思います。

テンプレートをcdtitleの要素に明示的に適用する必要はありません。通常はapply-templatesです。また、スタイルシートには現在storesizeなどのテンプレートがありません。私が理解する限り、これらの要素はコンテンツがHTML出力のtd要素の中に入る要素なので、それらのテンプレートはむしろ一般的であってもテンプレートと一致させる必要があります。

あなたは、事前にテーブルヘッダthの名前を知らないとalbumの孫ですリーフ要素の変数の数がある場合は、ここではより多くの「ダイナミック」ソリューションの場合:

XSLTスタイルシートは

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" 
     encoding="UTF-8" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
     <html> 
      <body> 
       <h2>My CD Collection</h2> 
       <table border="1"> 
        <tr bgcolor="#cccccc"> 
         <xsl:for-each select="distinct-values(catalog/rock/album/*/*/name())"> 
          <th style="text-align:left"> 
           <xsl:value-of select="."/> 
          </th> 
         </xsl:for-each> 
        </tr> 
        <xsl:apply-templates/> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="album"> 
     <tr> 
      <xsl:apply-templates/> 
     </tr> 
    </xsl:template> 

    <xsl:template match="album/*/*"> 
     <td> 
      <xsl:value-of select="."/> 
     </td> 
    </xsl:template> 

</xsl:stylesheet> 

HTML出力

<!DOCTYPE html 
    PUBLIC "XSLT-compat"> 
<html> 
    <body> 
     <h2>My CD Collection</h2> 
     <table border="1"> 
     <tr bgcolor="#cccccc"> 
      <th style="text-align:left">title</th> 
      <th style="text-align:left">artist</th> 
      <th style="text-align:left">store</th> 
      <th style="text-align:left">size</th> 
     </tr> 
     <tr> 
      <td>Empire Burlesque</td> 
      <td>Bob Dylan</td> 
      <td>Apple</td> 
      <td>3823</td> 
     </tr> 
     <tr> 
      <td>Hide your heart</td> 
      <td>Bonnie Tyler</td> 
      <td>Amazon</td> 
      <td>2123</td> 
     </tr> 
     </table> 
    </body> 
</html> 

レンダリングされたHTML

enter image description here

オンラインhereこのソリューションをお試しください。

+0

あなたのソリューションと迅速な対応に感謝します。私は "私はXSLTの新機能"で質問を始めたくないが、これは私の最初の解決策を試した後、私は今現代のWebブラウザがまだXSLT 1.0を使用していることを認識している!それでも、私はこれが最高の答えであると確信しています。そして幸いにも私のアプリケーションはXSLT 2.0を使用しています。 [リンク](http://xsltransform.net)へのリンクも便利でしたが、私はそのようなウェブサイトを知らなかった。再度、感謝します! – MasterWill

1

私は正しく推測している場合は、あなたのような何かをしたい:

XSLT 1.0

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

<xsl:template match="/catalog"> 
    <html> 
     <body> 
      <h2>My CD Collection</h2> 
      <table border="1"> 
       <tr> 
        <xsl:apply-templates select="*/album[1]" mode="header"/> 
       </tr> 
       <xsl:apply-templates/> 
      </table> 
     </body> 
    </html> 
</xsl:template> 

<xsl:template match="album"> 
    <tr> 
     <xsl:apply-templates/> 
    </tr> 
</xsl:template> 

<xsl:template match="*[text()]" mode="header"> 
    <th> 
     <xsl:value-of select="name()"/> 
    </th> 
</xsl:template> 

<xsl:template match="*[text()]"> 
    <td> 
     <xsl:value-of select="."/> 
    </td> 
</xsl:template> 

</xsl:stylesheet> 

これは、すべてのalbumの行を作成し、持つすべてのリーフノードの列をテキストノード。

これは入力が通常のものであることを前提としています。つまり、すべてのアルバムが同じ順序で同じプロパティを持ち、いずれも空ではないということです。

+0

私はこれをテストしていませんが、XSLT 1.0にとっては良いスタートアップのようです。問題は、私の場合、アルバムは違う性質を持っているかもしれないし、ランダムな順序であって空の結果が出る可能性があるということだ。 – MasterWill

+0

それでは、これも受け入れられた答えもあなたのためには役に立たないでしょう。 –

+0

どのように?受け入れられた答えは私の問題に適していたし、私はこの非常にイライラしている可能性が非常に有用な技術に新しいので、私にさらなる洞察力を与えた:) – MasterWill

関連する問題