应用XSLT进行菜单呈现转换

来源:互联网 发布:棕色淘宝首页图片欣赏 编辑:程序博客网 时间:2024/05/29 16:28

       XSLT不多解释,大家都知道,它是扩展样式表转换语言(ExtensibleStylesheet Language Transformations)的简称,这是一种对XML文档进行转化的语言。

      应用XSLT我们可以将复杂的HTML呈现视图的维护,变成相对轻量级、可扩展、可预测、可动态化的维护,避免自定义实现的动态编程等烦恼,好处多多……,本文主要介绍基于特定XML文档视图的情况下,根据业务需求定制合适的系统菜单(接上篇《复杂系统权限控制、设计另类方案》),细枝末节不在赘述。

      涉及XML,顺带提一下:Visual IDE没有像Eclipse那样通过设定dtd、关联xml自动校验出xml是否合法,如果存在与远程接口交互XML,则比对XML格式非常麻烦,当然可以通过VS的代码方式编程来实现验证,略显愚笨;所以如提供外部服务XML接口,建议采用其他方式制作DTD。

§ 全局菜单

1、 构造XML文档

XML文档视图由前面的步骤根据业务需求&业务逻辑生成,视图如下:

<?xml version="1.0" encoding="utf-8" ?><menu>  <menuitem id="TEST_MGR_ACCOUNT" name="test" url="/AccountIndex.aspx" target="">    <menuitem id="TEST_ACC_HOME" name="test" url="/AccountIndex.aspx" target="" />    <menuitem id="TEST_ACC_INFO" name="test" url="/AccountInfo.aspx" target="" />    <menuitem id="TEST_ACC_DETAIL" name="test" url="/AccountList.aspx" target="" />    <menuitem id="TEST_ACC_SUMMARY" name="test" url="/AccountSummary.aspx" target="" />    <menuitem id="TEST_ACC_REC_DOWN" name="test" url="/ReconOrder.aspx" target="" />  </menuitem>  <menuitem id="TEST_MGR_FUND" name="test" url="/DepositIndex.aspx" target="">    <menuitem id="TEST_MGR_DEPOSIT" name="test" url="/DepositIndex.aspx" target="">      <menuitem id="TEST_D_DEPOSIT" name="test" url="/MerchantDeposit.aspx" target="" />    </menuitem>    <menuitem id="TEST_MGR_PAYMENT" name="test" url="/PayIndex.aspx" target="">      <menuitem id="TEST_P_APPLY" name="test" url="/PayIndex.aspx" target="" />    </menuitem>    <menuitem id="TEST_MGR_RECEIVE" name="test" url="/ReceiveIndex.aspx" target="" />    <menuitem id="TEST_MGR_WITHDRAW" name="test" url="/SettleIndex.aspx" target="">      <menuitem id="TEST_WITH_SELF" name="test" url="/MerchantSettle.aspx" target="" />      <menuitem id="TEST_WITH_COMM" name="test" url="/MerchantDelegateSettle.aspx" target="" />    </menuitem>  </menuitem>  <menuitem id="TEST_ALL_QUERY" name="test" url="/OrderQuery.aspx" target="">    <menuitem id="TEST_TRANS_QUERY" name="test" url="/OrderQuery.aspx" target="" />    <menuitem id="TEST_BENEFIT_QUERY" name="test" url="/ShareBenefit.aspx" target="" />    <menuitem id="TEST_REF_QUERY" name="test" url="/RefundList.aspx" target="" />  </menuitem>  <menuitem id="TEST_MGR_USER" name="test" url="/OperatorList.aspx" target="">    <menuitem id="TEST_MGR_OPERATOR" name="test" url="/OperatorList.aspx" target="" />    <menuitem id="TEST_USER_ROLE" name="test" url="/OperatorRoleList.aspx" target="" />  </menuitem>  <menuitem id="TEST_MGR_APPROVE" name="test" url="/ApproveRequests.aspx" target="">    <menuitem id="TEST_A_APPLY_LOG" name="test" url="/ApproveRequests.aspx" target="" />    <menuitem id="TEST_A_APPROVE_SETTING" name="test" url="/ProductApproveSetting.aspx" target="" />  </menuitem>  <menuitem id="TEST_MGR_GROUP" name="test" url="/GroupMembers.aspx" target="">    <menuitem id="TEST_GP_HOME" name="test" url="/GroupMembers.aspx" target="" />    <menuitem id="TEST_GP_MONITOR" name="test" url="/GroupPaymentQuery.aspx" target="" />    <menuitem id="TEST_GP_COLLECT" name="test" url="/GroupFundCollect.aspx" target="" />    <menuitem id="TEST_GP_DISTRIBUTE" name="test" url="/GroupFundDistribute.aspx" target="" />    <menuitem id="TEST_GP_APPROVE" name="test" url="/GroupApproveRequests.aspx" target="">      <menuitem id="TEST_GP_A_QUOTA" name="test" url="/GroupMemberQuota.aspx" target="" />    </menuitem>  </menuitem>  <menuitem id="PRODUCT_CENTER" name="test" url="/PosTrades.aspx" target="">    <menuitem id="TEST_MGR_POS" name="test" url="/PosTrades.aspx" target="">      <menuitem id="TEST_POS_MACHINE" name="test" url="/InstrumentQuery.aspx" target="" />      <menuitem id="TEST_POS_PROMOTER" name="test" url="/ExpandQuery.aspx" target="" />      <menuitem id="TEST_POS_TERMINAL" name="test" url="/TerminalList.aspx" target="" />      <menuitem id="TEST_POS_TRADE" name="test" url="/PosTrades.aspx" target="" />      <menuitem id="TEST_POS_RULE" name="test" url="/ShareBenefitRule.aspx" target="" />      <menuitem id="TEST_POS_SETTLE" name="test" url="/SettleApplyQuery.aspx" target="" />    </menuitem>  </menuitem>  <menuitem id="TEST_MGR_SECURITY" name="test" url="/SafeCenter.aspx" target="">    <menuitem id="TEST_SEC_HOME" name="test" url="/SafeCenter.aspx" target="" />    <menuitem id="TEST_SEC_DIGITAL" name="test" url="/CertiMng.aspx" target="" />    <menuitem id="TEST_SEC_EKEY" name="test" url="/EkeyIndex.aspx" target="" />    <menuitem id="TEST_SEC_HIS" name="test" url="/CertiList.aspx" target="" />    <menuitem id="TEST_SEC_UKEY" name="test" url="/UKey.aspx" target="" />  </menuitem></menu>

2、 构造XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  <xsl:output method="html" encoding="utf-8"/>  <xsl:template match="/">    <div>      <div class="page_head_tabs" style="width:1000px;">        <ul>          <xsl:for-each select="menu/menuitem">            <li class="head_tab_item">              <xsl:attribute name="id">                <xsl:value-of select="@id"></xsl:value-of>              </xsl:attribute>              <a>                <xsl:attribute name="href">                  <xsl:value-of select="@url"></xsl:value-of>                </xsl:attribute>                <span>                  <xsl:value-of select="@name"></xsl:value-of>                </span>              </a>            </li>          </xsl:for-each>        </ul>      </div>      <div class="css_hack">'      </div>      <xsl:for-each select="menu/menuitem">        <div class="page_head_menu" style="display:none;">          <xsl:attribute name="id">            <xsl:value-of select="@id"></xsl:value-of>            <xsl:text>_sub</xsl:text>          </xsl:attribute>          <ul>            <xsl:for-each select="child::*">              <li class="menu_item">                <xsl:attribute name="id">                  <xsl:value-of select="@id"></xsl:value-of>                </xsl:attribute>                <a>                  <xsl:attribute name="href">                    <xsl:value-of select="@url"></xsl:value-of>                  </xsl:attribute>                  <xsl:attribute name="target">                    <xsl:choose>                      <xsl:when test="@target = '#'">                        <xsl:text>_self</xsl:text>                      </xsl:when>                      <xsl:when test="@target != '#'">                        <xsl:value-of select="@target"></xsl:value-of>                      </xsl:when>                    </xsl:choose>                  </xsl:attribute>                  <span>                    <xsl:value-of select="@name"></xsl:value-of>                  </span>                </a>              </li>            </xsl:for-each>          </ul>        </div>      </xsl:for-each>    </div>  </xsl:template></xsl:stylesheet>

3、 XSLT转换

        private static Cache cache = HttpRuntime.Cache;        /// <summary>        /// XML转换对象        /// </summary>        /// <param name="xslPath"></param>        /// <returns></returns>        public static XslCompiledTransform GetXmlTrans(string xslPath, string xsltType)        {            XslCompiledTransform trans = cache[xsltType] as XslCompiledTransform;            if (trans == null)                trans = new XslCompiledTransform(false);            if (trans.OutputSettings == null)            {                lock (trans)                {                    trans.Load(xslPath);                    CacheDependency cacheDepends = new CacheDependency(xslPath);                    cache.Insert(xsltType, trans, cacheDepends);                }            }            return trans;        }

4、 HTML视图缓存
        /// <summary>        /// 设置菜单树缓存(Html)        /// </summary>        /// <param name="xml">xml结构文档</param>        /// <param name="xsltType">xslt转换类型:</param>        public void SetMenuHtml(string xml, string xsltType)        {            string xPath = ToolUtils.MenuXslt;            string sessionKey = AuthConsts.Keys.MENUS_HTML;            if (xsltType == SysFramework.Consts.XsltType.PRODUCECENTER)            {                xPath = ToolUtils.AppMenuXslt;                sessionKey = AuthConsts.Keys.APP_MENUS_HTML;            }            //get cached xslt            XslCompiledTransform xslt = ToolUtils.GetXmlTrans(xPath, xsltType);            TextReader tr = new StringReader(xml);            XPathDocument xpath = new XPathDocument(tr);            StringBuilder sb = new StringBuilder();            using (XmlWriter sw = XmlWriter.Create(sb))            {                xslt.Transform(xpath, null, sw);            }            //fixed microsoft bug, replace[<?xml version="1.0" encoding="utf-16"?>]            xml = Regex.Replace(sb.ToString(), @"<\?xml[^>]+.", "");            if (HttpContext.Current == null || HttpContext.Current.Cache[sessionKey] == null)            {                CacheHelper.SetSessionValue<string>(sessionKey, xml);                //AuthLogger.Info("Initialize-SetMenuHtml:" + xml);            }        }

      由于采用了全局菜单&访问权限验证的方式,所以此次将全局菜单Cached

§ 局部应用接入菜单

1、 构造XML文档

2、 构造XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  <xsl:output method="html" encoding="utf-8"/>  <xsl:template match="/">    <div class="col-sub">      <xsl:for-each select="menu/menuitem">        <dl class="menu">          <dt>            <span>              <xsl:value-of select="@name"></xsl:value-of>            </span>          </dt>          <dd>            <xsl:for-each select="child::*">              <xsl:call-template name="LeverTwo">              </xsl:call-template>            </xsl:for-each>          </dd>        </dl>      </xsl:for-each>    </div>  </xsl:template>  <xsl:template name="LeverTwo">    <a target="appIframe">      <xsl:attribute name="href">        <xsl:text>/manage/appendpoint.aspx?id=</xsl:text>        <xsl:value-of select="@id"></xsl:value-of>      </xsl:attribute>      <xsl:value-of select="@name"></xsl:value-of>    </a>    <xsl:call-template name="LeverThree"></xsl:call-template>  </xsl:template>  <xsl:template name="LeverThree">    <xsl:if test="child::*">      <p>        <xsl:for-each select="child::*">          <a target="appIframe">            <xsl:attribute name="href">              <xsl:text>/manage/appendpoint.aspx?id=</xsl:text>              <xsl:value-of select="@id"></xsl:value-of>            </xsl:attribute>            <xsl:value-of select="@name"></xsl:value-of>          </a>        </xsl:for-each>      </p>    </xsl:if>  </xsl:template></xsl:stylesheet>

3、 XSLT转换

4、 HTML视图缓存

§ 测试方法

       打开待测试XML文档,如图:

      

点击显示XSLT输出,弹出选择框,选定待解释的XSLT路径,编译、呈现HTML。


原创粉丝点击