1

は最近、サイト レイアウトと子ページを作成するための XSL/t の使用について質問しました。私はそのアイデアを拡張し、SiteMesh のような機能を考え出そうとしています。非常に少数の xsl レイアウト ファイルを使用することに注意してください。ほとんどの xsl ファイルは子ページ用である必要があります。レイアウトはかなり基本的なもので、ヘッダー、メイン メニュー、フッター、本文が含まれます。その下に content div があります。SiteMesh では、テンプレート ファイルをかなり標準的な html ファイルとして定義し、次に親のセクションを上書きする子ページを定義できます。たとえば、サイトメッシュの基本的なテンプレート (デコレータ) は次のとおりです。

<%@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/decorator" %>

<head>
  <title>
    <decorator:title default="SiteMesh Tutorial Example" /> - Site Title
  </title>
  <style type="text/css">@import "css/global.css";</style>
  <decorator:head />
  <body>
    <div id="header">
      <h2><a href="http://www.my-site.com/">Mysite.com</a> goes here</h2>
    </div>
    <div id="content">
      <decorator:body />
    </div>
  </body>
</html>

次に、子ページの例を次に示します。

<html>
  <head>
    <title>Child Page</title>
    <style type='text/css'> 
     p { margin: 10 }    
    </style>
  </head>
  <body>
    Content Goes here
  </body>
</html>

デコレータが子ページに適用されると、結果にはデコレータ:ボディがあった子ページのボディが含まれ 、デコレータ:ヘッドも同様に置き換えられます。サイトの整理。

そこで、代わりに XSL/T を使用していて、レイアウトがどのように見えるかを再定義し続けるのではなく、できれば一度だけ (または、そうでないページの場合は数回) 定義する同様の構造を使用したいとしましょう。 t 非常に似ています)、子テンプレートにセクションがある場合はそれらを置き換えます。これは非常に単純なように思えますが、問題は、このサイトを裏付けるデータが次のようになることです (実際にはブログ サイトではなく、私が扱っているものの例として)

<xml>
<section>Blogs</section>
<page>UserBlogs</page>
<data>
 <blogs>
   <blog>
     <title>First Blog</title>
     <author>John Doe</author>
     <description>...</description>
   </blog>
 </blogs>
</data>
</xml>

それでは、次のようなマスター テンプレートがあるとします。

<html>
<head>
  <title><!-- replace this with child title --> - Site Title</title>
  <script src="common-scripts.js"></script>
  <style type="text/css">@import "common.css" </style>
  <!-- insert everything in the child <head> here except the title -->

</head>
<body>
  <div id="header">Header/log that stuff here</div>
  <div id="menu">
     <ul><li><a href="#">Cat 1</a></li><li><a href="#">Cat 2</a></li></ul>
  </div>
  <div id="content">
    <!-- replace this with everything between <body>...</body> in the child -->
  </div>
  <div id="footer">My Site, copyright, bla bla</div>
</body>
</html>

それで、私がやりたいのは、上記のxml(ブログに関するもの)を取得して子ページに適用し、その変換の結果を取得してマスターテンプレートに適用することです(必要に応じて要素をコピー/適用します) )。1回の変換でこれを行う方法があるかどうかはわかりません。現在、アーキテクチャは、示されているように xml が提供されているようなものであり、それをページに構築する必要があります。マスター テンプレートに子テンプレートを含めてから、xsl:call-template をラップして使用できるのではないかと考えました。現在の xml で子テンプレートの結果を取得するための xsl:variable 宣言..マスター テンプレートのタイトル/ヘッダー/コンテンツ セクションを置き換えるには、その変換の結果を取得する必要があります。

これを行う方法はありますか?

私はこのサイトで見ます: http://www.devguru.com/technologies/xslt/quickref/xslt_element_calltemplate.html xsl:call-template の結果を xsl:variable 宣言でキャプチャできることその後、出力以外にそのデータを使用できます。

どんな助けでもいただければ幸いです

4

1 に答える 1

2

この入力で:

<xml>
    <section>Blogs</section>
    <page>UserBlogs</page>
    <data>
        <blogs>
            <blog>
                <title>First Blog</title>
                <author>John Doe</author>
                <description>...</description>
            </blog>
        </blogs>
    </data>
</xml>

この「master.xml」ドキュメント:

<html>
    <head>
        <title><!-- replace this with child title --> - My Site</title>
        <script src="common-scripts.js"></script>
        <style type="text/css">@import "common.css" </style>
        <!-- insert everything in the child <head> here except the title -->
    </head>
    <body>
        <div id="header">Header/log that stuff here</div>
        <div id="menu">
            <ul>
                <li>
                    <a href="#">Cat 1</a>
                </li>
                <li>
                    <a href="#">Cat 2</a>
                </li>
            </ul>
        </div>
        <div id="content">
            <!-- replace this with everything between 
                                   <body>...</body> in the child -->
        </div>
        <div id="footer">My Site, copyright, bla bla</div>
    </body>
</html>

この「child.xml」ドキュメント:

<html>
    <head>
        <title>Child Page</title>
        <style type='text/css'>p { margin: 10 }</style>
    </head>
    <body>
        <h3 id="title">#</h3>
        <dl>
            <dt id="author">#</dt>
            <dd id="description">#</dd>
        </dl>
    </body>
</html>

このスタイルシート:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"/>
    <xsl:variable name="child" select="document('child.xml')"/>

    <!-- From here to next comment could be in other stylesheet
         like "master.xsl" and included with "xsl:include"      -->

    <xsl:variable name="master" select="document('master.xml')"/>
    <xsl:template match="@*|node()">
        <xsl:param name="context"/>
        <xsl:copy>
            <xsl:apply-templates select="@*|node()">
                <xsl:with-param name="context" select="$context"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/">
        <xsl:apply-templates select="$master/*">
            <xsl:with-param name="context" select="/"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="div[@id='content']">
        <xsl:param name="context"/>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:for-each select="$context/xml/data/blogs/blog">
                <xsl:apply-templates select="$child/html/body/node()">
                    <xsl:with-param name="context" select="."/>
                </xsl:apply-templates>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="title/comment()">
        <xsl:param name="context"/>
        <xsl:value-of select="$context/xml/page"/>
    </xsl:template>
    <xsl:template match="head/comment()">
        <xsl:param name="context"/>
            <xsl:apply-templates 
                            select="$child/html/head/node()[not(self::title)]">
                <xsl:with-param name="context" select="$context"/>
            </xsl:apply-templates>
    </xsl:template>

    <!-- Here ends the posible "master.xsl" to be included -->

    <xsl:template match="@id[.='title']|@id[.='author']|@id[.='description']"/>
    <xsl:template match="*[@id='title']/text()">
        <xsl:param name="context"/>
        <xsl:value-of select="$context/title"/>
    </xsl:template>
    <xsl:template match="*[@id='author']/text()">
        <xsl:param name="context"/>
        <xsl:value-of select="$context/author"/>
    </xsl:template>
    <xsl:template match="*[@id='description']/text()">
        <xsl:param name="context"/>
        <xsl:value-of select="$context/description"/>
    </xsl:template>
</xsl:stylesheet>

出力:

<html>
    <head>
        <title>UserBlogs - My Site</title>
        <script src="common-scripts.js"></script>
        <style type="text/css">@import "common.css" </style>
        <style type="text/css">p { margin: 10 }</style>
    </head>
    <body>
        <div id="header">Header/log that stuff here</div>
        <div id="menu">
            <ul>
                <li>
                    <a href="#">Cat 1</a>
                </li>
                <li>
                    <a href="#">Cat 2</a>
                </li>
            </ul>
        </div>
        <div id="content">
            <h3 id="title">First Blog</h3>
            <dl>
                <dt id="author">John Doe</dt>
                <dd id="description">...</dd>
            </dl>
        </div>
        <div id="footer">My Site, copyright, bla bla</div>
    </body>
</html>

: これは単なる例です。もっとよくなるはず。人口パターンに関する主要な問題: ロジックはデータではなくレイアウトをトラバースし、主に恒等変換を使用します。データを参照するには、レイアウトにいくつかのアンカーが必要です (これは、たとえば、独自の名前空間によってid="include:some-data"、などの特定のパターンによって改善するために広く開かれています)。それらがそうである場合、それらのアンカーを削除する必要があり@idます。テキスト置換の場合、レイアウトでダミー テキスト ノードを使用します。これにより、コンテンツ テンプレートがxsl:value-of;だけで簡素化されます。データ コンテキストを渡すための「貧乏人のトンネル パターン」(Dimitre 呼び出し)。主に人口の反復によるものです。その他の問題: XHTML (HTML よりも優れている) を扱う場合は次の点に注意してください: 主に IE7 用の DOCTYPE (改善された CSS 処理が緩い、そうでない場合)、DTD で宣言された空の要素 (<br />それ以外は)。以前に投稿したサイトを自由にチェックして、それらをどのように処理したかを確認してください。

于 2010-08-20T17:14:27.873 に答える