2

xsltを使用して動的テーブル(グリッド)を作成していますが、

XSLT :

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

     <xsl:key name="RowAttribsByName" match="Row/@*"

      use="concat(generate-id(..), '|', name())"/>

 <xsl:variable name="vColNames" select=
  "/*/Columns/*[not(@Hidden = 'true')]/@Name"/>

 <xsl:template match="/*">
  <table border="1">
    <tr>
     <xsl:apply-templates select="Columns/*"/>
    </tr>
    <xsl:apply-templates select="Rows/Row"/>
  </table>
 </xsl:template>

 <xsl:template match="Column[not(@Hidden = 'true')]">
  <td><xsl:value-of select="@Caption"/></td>
 </xsl:template>

 <xsl:template match="Row">
  <tr>
   <xsl:apply-templates select="$vColNames">
     <xsl:with-param name="pRowId"
          select="generate-id()"/>
   </xsl:apply-templates>
  </tr>
 </xsl:template>

 <xsl:template match="Column/@*">
  <xsl:param name="pRowId"/>

  <td width="50%">
    <xsl:value-of select=
      "key('RowAttribsByName',
           concat($pRowId, '|', .)
           )
    "/>
  </td>
 </xsl:template>
</xsl:stylesheet>

XML データ :

<TableData>
    <Columns>
        <Column Name="ID" Hidden="true" />
        <Column Name="Name" Caption="Item Name" Link="Yes" Sort="Yes"/>
        <Column Name="Desc" Caption="Item Description" />
    </Columns>
    <Rows>
        <Row ID="0" Name="A" />
        <Row ID="1" Name="B" Desc="Some description"/>
        <Row ID="3" Name="C" />
    </Rows>
</TableData>

期待される出力:

<table border="1">
    <tbody>
        <tr>
            <td>
                <a onclick="javascript:SortColumn('Item Name')">Item Name</a>
            </td>
            <td>
                <a onclick="javascript:SortColumn('Item Description')">Item Name</a></td>
        </tr>
        <tr>
            <td width="50%">
                <a onclick="javascript:OpenDifferentPage('A','0')">A</a>
            </td>
            <td width="50%"></td>
        </tr>
        <tr>
            <td width="50%">B</td>
            <td width="50%">Some description</td>
        </tr>
        <tr>
            <td width="50%">C</td>
            <td width="50%"></td>
        </tr>
    </tbody>
</table>

私は XSLT の初心者です。

ここで、列に「リンク」属性が「はい」の場合、アンカータグ(名前)の間にデータを表示する必要があることを確認したいと思います。

私はこのコラムで多くの複雑な機能を作成しています。したがって、ここで特定の列のテンプレートを作成できます(列は15ですが、ユーザーが表示用に8列を選択し、列の順序を維持する必要がある場合は、ユーザーの選択に依存します

列のデータが渡されるように、列の順序を維持してすべての列の新しいテンプレートを作成できる場合が最善です。

ご期待いただきありがとうございます

4

2 に答える 2

2

XSLT の初心者の場合、特にxsl:keyを使用することで、ここからすでに非常に良いスタートを切ることができます。

あなたの差し迫った質問に答えるために、現在のように要素の属性に一致する単一のテンプレートを使用する代わりに、何ができるでしょうか....

<xsl:template match="Column/@*">

Link属性が設定されている場合、それに一致する明示的なテンプレートを持つことができます

<xsl:template match="Column[@Link='Yes']/@*">

このテンプレートでは、コードを追加しリンクを出力できます。Row のgenerate-idの値とは対照的に、実際のRowをパラメーターとして渡すと、 ID属性を取得するための冗長性がわずかに軽減されるため、少し簡単になる可能性があることに注意してください。

 <xsl:template match="Column[@Link='Yes']/@*">
  <xsl:param name="pRow"/>
  <xsl:variable name="pRowId" select="generate-id($pRow)"/>
  <xsl:variable name="pValue" select="key('RowAttribsByName', concat($pRowId, '|', .))" />
  <td width="50%">
     <a onclick="javascript:OpenDifferentPage('{$pValue}','{$pRow/@ID}')">
        <xsl:value-of select="$pValue"/>
     </a>
  </td>
 </xsl:template>

onclick属性を作成する際に、ここで属性値テンプレートを使用していることに注意してください。中括弧は、文字どおりに出力するのではなく、評価する式を示します。

ただし、このテンプレートを機能させるには、リンク属性が「はい」に設定されていない明示的な一致属性に他のテンプレートを修正する必要もあります。

<xsl:template match="Column[not(@Link='Yes')]/@*">

これは、そうしないと、元のテンプレートが新しいテンプレートと同じ優先度で「はい」であるリンクのケースと一致するためです。これは許可されていません。

このXSLTを試してください

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output omit-xml-declaration="yes" indent="yes"/>
   <xsl:key name="RowAttribsByName" match="Row/@*" use="concat(generate-id(..), '|', name())"/>
   <xsl:variable name="vColNames" select="/*/Columns/*[not(@Hidden = 'true')]/@Name"/>

   <xsl:template match="/*">
      <table border="1">
         <tr>
            <xsl:apply-templates select="Columns/*"/>
         </tr>
         <xsl:apply-templates select="Rows/Row"/>
      </table>
   </xsl:template>

   <xsl:template match="Column[not(@Hidden = 'true')]">
      <td>
         <xsl:value-of select="@Caption"/>
      </td>
   </xsl:template>

   <xsl:template match="Row">
      <tr>
         <xsl:apply-templates select="$vColNames">
            <xsl:with-param name="pRow" select="."/>
         </xsl:apply-templates>
      </tr>
   </xsl:template>

   <xsl:template match="Column[not(@Link='Yes')]/@*">
      <xsl:param name="pRow"/>
      <xsl:variable name="pRowId" select="generate-id($pRow)"/>
      <xsl:variable name="pValue" select="key('RowAttribsByName', concat($pRowId, '|', .))"/>
      <td width="50%">
         <xsl:value-of select="$pValue"/>
      </td>
   </xsl:template>

   <xsl:template match="Column[@Link='Yes']/@*">
      <xsl:param name="pRow"/>
      <xsl:variable name="pRowId" select="generate-id($pRow)"/>
      <xsl:variable name="pValue" select="key('RowAttribsByName', concat($pRowId, '|', .))"/>
      <td width="50%">
         <a onclick="javascript:OpenDifferentPage('{$pValue}','{$pRow/@ID}')">
            <xsl:value-of select="$pValue"/>
         </a>
      </td>
   </xsl:template>
</xsl:stylesheet>

このアプローチには、いくつかの欠点があります。いくつかの繰り返しコードがあり、列の出力に影響を与える列要素に他の属性がある場合は、管理が難しくなります。

これは、 mode要素を使用して Column 属性を繰り返し照合する XSLT の別のバージョンで、必要に応じてより多くの要素を出力できる可能性があります。

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output omit-xml-declaration="yes" indent="yes"/>
   <xsl:key name="RowAttribsByName" match="Row/@*" use="concat(generate-id(..), '|', name())"/>
   <xsl:variable name="vColNames" select="/*/Columns/*[not(@Hidden = 'true')]/@Name"/>

   <xsl:template match="/*">
      <table border="1">
         <tr>
            <xsl:apply-templates select="Columns/*"/>
         </tr>
         <xsl:apply-templates select="Rows/Row"/>
      </table>
   </xsl:template>

   <xsl:template match="Column[not(@Hidden = 'true')]">
      <td>
         <xsl:value-of select="@Caption"/>
      </td>
   </xsl:template>

   <xsl:template match="Row">
      <tr>
         <xsl:apply-templates select="$vColNames">
            <xsl:with-param name="pRow" select="."/>
         </xsl:apply-templates>
      </tr>
   </xsl:template>

   <xsl:template match="Column/@Name">
      <xsl:param name="pRow"/>
      <xsl:variable name="pRowId" select="generate-id($pRow)"/>
      <xsl:variable name="pValue" select="key('RowAttribsByName', concat($pRowId, '|', .))"/>
      <td width="50%">
         <xsl:apply-templates select=".." mode="link">
            <xsl:with-param name="pRow" select="$pRow"/>
            <xsl:with-param name="pValue" select="$pValue"/>
         </xsl:apply-templates>
      </td>
   </xsl:template>

   <xsl:template match="Column[@Link='Yes']" mode="link">
      <xsl:param name="pRow"/>
      <xsl:param name="pValue"/>
      <a onclick="javascript:OpenDifferentPage('{$pValue}','{$pRow/@ID}')">
         <xsl:apply-templates select="self::*" mode="value">
            <xsl:with-param name="pRow" select="$pRow"/>
            <xsl:with-param name="pValue" select="$pValue"/>
         </xsl:apply-templates>
      </a>
   </xsl:template>

   <xsl:template match="Column" mode="link">
      <xsl:param name="pRow"/>
      <xsl:param name="pValue"/>
      <xsl:apply-templates select="self::*" mode="value">
         <xsl:with-param name="pRow" select="$pRow"/>
         <xsl:with-param name="pValue" select="$pValue"/>
      </xsl:apply-templates>
   </xsl:template>

   <xsl:template match="Column" mode="value">
      <xsl:param name="pRow"/>
      <xsl:param name="pValue"/>
      <xsl:value-of select="$pValue"/>
   </xsl:template>
</xsl:stylesheet>

この例では、リンクに 2 つのテンプレートがあることに注意してください。

<xsl:template match="Column[@Link='Yes']" mode="link">

<xsl:template match="Column" mode="link">

この場合、2 番目はLink属性のチェックを必要としません。テンプレートが明示的な要素名と一致するだけの場合、xpath 式で修飾されたテンプレートよりも優先度が低くなります。したがって、2 番目のテンプレートは、 Linkが Yesの場合には一致しません。

于 2013-08-03T10:49:42.093 に答える
1

この XSLT 1.0 スタイルシート...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:key name="linked-cols" match="Column[@Link='Yes']" use="@Name" />

<xsl:template match="TableData">
  <table border="1">
    <tbody>
      <xsl:variable name="cols" select="count(Columns/Column[not(@Hidden='true')])" />
      <xsl:apply-templates>
        <xsl:with-param name="col-width" select="concat(100 div $cols,'%')" />
      </xsl:apply-templates> 
    </tbody>
  </table>
</xsl:template>

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

<xsl:template match="Column[@Hidden='true']" />

<xsl:template match="Column[@Sort='Yes']">
  <td>
    <a onclick="javascript:SortColumn('{@Caption}')"><xsl:value-of select="@Caption" /></a>
  </td>
</xsl:template>

<xsl:template match="Column">
  <td><xsl:value-of select="@Caption" /></td>
</xsl:template>

<xsl:template match="Rows">
  <xsl:param name="col-width" />
  <xsl:apply-templates>
    <xsl:with-param name="col-width" select="$col-width" />
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="Row">
  <xsl:param name="col-width" />
  <tr>
    <xsl:variable name="Row" select="." />
    <xsl:for-each select="../../Columns/Column[not(@Hidden='true')]">
      <td width="{$col-width}">
        <xsl:variable name="col-name" select="@Name" />
        <xsl:apply-templates select="$Row/@*[local-name() = $col-name]" />
      </td>  
    </xsl:for-each>
  </tr>
</xsl:template>

<xsl:template match="Row/@*">
  <xsl:value-of select="." />
</xsl:template>

<xsl:template match="Row/@*[key('linked-cols',local-name())]">
  <a onclick="javascript:OpenDifferentPage('{.}','{../@ID}')"><xsl:value-of select="." /></a>
</xsl:template>

</xsl:stylesheet>

... このドキュメントに適用すると ...

<TableData>
    <Columns>
        <Column Name="ID" Hidden="true" />
        <Column Name="Name" Caption="Item Name" Link="Yes" Sort="Yes"/>
        <Column Name="Desc" Caption="Item Description" />
    </Columns>
    <Rows>
        <Row ID="0" Name="A" />
        <Row ID="1" Name="B" Desc="Some description"/>
        <Row ID="3" Name="C" />
    </Rows>
</TableData>

... が得られます ...

<!DOCTYPE html SYSTEM "about:legacy-compat">
<table border="1">
  <tbody>
    <tr>
      <td><a onclick="javascript:SortColumn('Item Name')">Item Name</a></td>
      <td>Item Description</td>
    </tr>
    <tr>
      <td width="50%"><a onclick="javascript:OpenDifferentPage('A','0')">A</a></td>
      <td width="50%"></td>
    </tr>
    <tr>
      <td width="50%"><a onclick="javascript:OpenDifferentPage('B','1')">B</a></td>
      <td width="50%">Some description</td>
    </tr>
    <tr>
      <td width="50%"><a onclick="javascript:OpenDifferentPage('C','3')">C</a></td>
      <td width="50%"></td>
    </tr>
  </tbody>
</table>
于 2013-08-04T08:19:18.990 に答える