XSLT - 创建动态网格 [英] XSLT - Creating Dynamic Grid

查看:33
本文介绍了XSLT - 创建动态网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 xslt 创建动态表(网格),

I am creating dynamic table(grid) using 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 的初学者,

I am beginner in XSLT,

我想在这里检查如果列有链接"属性=是",那么我需要在锚标记(名称)之间显示数据.

I want to check here that If column have "Link" attribute ="yes" then i need to display Data in between anchor tag(Name).

我在这个专栏上创建了许多复杂的功能.所以这里我可以为特定的列制作模板(列是 15,但这取决于用户的选择,如果用户选择 8 列进行显示,并且它必须保持列的顺序)

I am create many complex functionality on this column. So here can i made template for particular columns(Column are 15 but it depend on user selection, if user select 8 column for display and also it must maintain ORDER of Columns)

最好是,如果我可以为所有列创建新模板,并根据传递的列数据保持列顺序.

It is best that if i can create new templates for all columns with maintain column Order as per Columns data are passed.

感谢您的期待

推荐答案

对于 XSLT 的初学者,您已经有了一个很好的开始,尤其是使用 xsl:key.

For a beginner in XSLT, you are already off to a very good start here, especially with the use of xsl:key.

要回答您的直接问题,您可以做什么,而不是像目前那样使用与 Column 元素的属性匹配的单个模板....

To answer your immediate question, what you could do, instead of having a single template matching the attributes of the Column elements as presently....

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

当设置了 Link 属性时,您可以有一个与之匹配的显式模板

You can have an explicit template matching it when the Link attribute is set

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

在这个模板中,您可以添加额外的代码来输出a链接.请注意,如果您将实际的 Row 作为参数传入,而不是 Row 的 generate-id 的值,则可能会稍微简单一些,因为这将使获取 ID 属性稍微不那么冗长.

In this template, you could add extra code to output the a link. Note that, it might be slightly simpler if you pass in the actual Row as a parameter, as opposed to the value of generate-id for the Row, as this would make it slightly less verbose to get the ID attribute.

 <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 属性时使用了属性值模板.花括号表示要计算的表达式,而不是字面上的输出.

Note the use of Attribute Value Templates here, in creating the onclick attributes. The curly braces indicate an expression to be evaluated, rather than output literally.

为了使此模板正常工作,您还需要修改另一个模板以显式匹配 Link 属性未设置为是"的属性

For this template to work though, you would also need to amend the other template to explicit match attributes where the Link attribute was not set to 'Yes'

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

这是因为否则原始模板将匹配链接为是"的情况,与新模板具有相同的优先级,这是不允许的.

This is because otherwise the original template would match the case of Link being "Yes" with the same priority as the new template, which is not allowed.

试试这个 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>

这种方法有几个缺点.有一些重复的代码,而且如果您在 Column 元素上有其他影响列输出的属性,那么管理起来也会更加困难.

This approach has a couple of drawbacks. There is some repeated code, and also it would be harder to manager if you had other attributes on the Column elements which affected the output of the columns.

这是 XSLT 的另一个版本,它利用 mode 元素重复匹配 Column 属性,允许您在需要时输出更多元素

Here is another version of the XSLT, which makes use of the mode element to repeatedly match the Column attribute, allowing you to potentially output more elements if required

<?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>

请注意,在此示例中,链接

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

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

在这种情况下,第二个不需要检查 Link 属性.当模板只匹配一个显式元素名称时,它的优先级将低于使用 xpath 表达式限定的优先级.因此,第二个模板永远不会匹配 Link 为 Yes 的情况.

In this case, the second does not need a check on the Link attribute. Where a template just matches an explicit element name, it will have a lower priority than one that has been qualified with an xpath expression. Therefore the second template will not ever match the case where Link is Yes.

这篇关于XSLT - 创建动态网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆