ajax addparam,Jigar Desai - XSLT Transformation in ASP.net MVC framework

XSLT Transformation in ASP.net MVC framework

Saturday, February 9, 2008

In my last post I talked about using a partial view to render hierarchical data, however XSL transformation looks more appropriate for such cases. ASP.Net has XML control which can display XML document using XSL Transformations. I will show you how similar thing can be achieved in ASP.NET MVC Framework.

The Model

I have a very simple Tab class which can have a collection of sub-tab. this class can be used to create infinite level of tab hierarchy. I have added XmlAttributes to my properties so that when class is serialized those properties are sterilized as attributes.

public class

Tab {

[XmlAttribute(

"id"

)]

public int

ID {

get; set;

}

[XmlAttribute(

"name"

)]

public string

Name {

get; set;

}

[XmlAttribute(

"alias"

)]

public string

Alias {

get; set;

}

public

List Tabs {

get; set;

}

}

The Controller

I have a single controller called TabController it has TabXSLT action, it does two things 1) Gets list of tabs from by calling service and then serializes it to XML and 2) Passes that XML to view.

public class

TabController : Controller {

[ControllerAction]

public void

TabXSLT() {

List tabs

=

TabService.GetTabs()

;

XmlSerializer serilizer

=

new

XmlSerializer(

typeof

(List))

;

MemoryStream stream

= new

MemoryStream()

;

stream.Seek(

0

, SeekOrigin.Begin)

;

serilizer.Serialize(stream, tabs)

;

XmlDocument doc

= new

XmlDocument()

;

stream.Seek(

0

, SeekOrigin.Begin)

;

doc.Load(stream)

;

ViewData[

"tabs"

]

=

doc

;

RenderView(

"TabXSLT"

)

;

}

}

View extension for XSLT

MVC Framework does not have concept of the control, Instead UI Helpers and ViewExtensions will enable you to wrap common functionality. I have used view extension in my case to inject additional method in view which will allow me render transformed XML inside my view.

public static class

XSLTViewExtensions {

public static void

RenderXML(

this

ViewPage page

, XmlDocument xmlDocument

,

string

XSLTPath,

Dictionary<

string

,

string

> xslArgParams)

{

ViewContext context

=

page.Html.ViewContext

;

XsltArgumentList xslArgs

= new

XsltArgumentList()

;

if

(xslArgParams !

= null

) {

foreach

(

string

key

in

xslArgParams.Keys) {

xslArgs.AddParam(key,

null

,xslArgParams[key])

;

}

}

XslCompiledTransform t

= new

XslCompiledTransform()

;

t.Load(XSLTPath)

;

t.Transform(xmlDocument, xslArgs,

context.HttpContext.Response.Output)

;

}

}

The View

I have the TabXSLT.aspx view in /Views/Tab folder. Inside my view I am calling extension method by passing XML data that I got from controller and path to XSLT file.

<

%@

Page Language

="C#"

Inherits

="System.Web.Mvc.ViewPage"

MasterPageFile

="~/Views/Shared/Site.Master"

%

>

<

%@

Import Namespace

="ExperimentsWithMVC.Models"

%

>

<

%@

Import Namespace

="System.Collections.Generic"

%

>

<

%@

Import Namespace

="System.Web.Mvc"

%

>

<

%@

Import Namespace

="System.Xml"

%

>

<

asp:Content

ID

="Content2"

ContentPlaceHolderID

="MainContentPlaceHolder"

runat

="server">

<

h2

>

Tabs with XSLT

h2

>

<

%

this.RenderXML((XmlDocument)ViewData[

"tabs"]

, Server.MapPath(

"~/content/tabs.xsl"),null);%>

asp:Content

>

The XSLT

<

?xml

version

="1.0"

encoding

="utf-8"?>

<

xsl:stylesheet

version

="1.0"

xmlns:xsl

="http://www.w3.org/1999/XSL/Transform"

>

<

xsl:output

omit-xml-declaration

="yes"

/>

<

xsl:template

match

="/">

<

xsl:apply-templates

>

xsl:apply-templates

>

xsl:template

>

<

xsl:template

match

="Tab">

<

li

>

<

xsl:value-of

select

="@name"/>

<

xsl:apply-templates

select

="Tabs">

xsl:apply-templates

>

li

>

xsl:template

>

<

xsl:template

match

="Tabs">

<

ul

>

<

xsl:apply-templates

select

="Tab"

/>

ul

>

xsl:template

>

<

xsl:template

match

="ArrayOfTab">

<

ul

>

<

xsl:apply-templates

select

="Tab"

/>

ul

>

xsl:template

>

xsl:stylesheet

>

The result

Result is nested unordered list as shown below, each item can have sub item up to nth level.

a6ae09dc7db365209c76e96f9bfb3d03.png

Parting Thoughts

I have used extension method to inject additional method in my current ViewPage class but it might be more appropriate to group similar UI helper methods in static class, for example you can have AJAXHelper, HTMLHelper, XMLHelper etc.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
try{ //1.获取参数值YX220 String rolepks = YSPubUtils.getExpHintLoanByRole(pk_corp); //2.查询出参数值为空,则全部角色提示 if(YCPubUtils.isEmpty(rolepks)){ return true; } //3.当前登录用户为空,不提示 if (YCPubUtils.isEmpty(userpk)){ return false; } String[] roles = rolepks.split(YCConstants.STRING_SPLIT_SEMICOLON); //从YX220参数获取不需要提示【是否借款】的角色pk Set<String> rolepkSet = new HashSet<String>(Arrays.asList(roles)); //4.根据当前登录用户PK和公司,查询出该用户的角色PK String sql = "select pk_role from sm_user_role where cuserid = ? and pk_corp = ? and isnull(dr,0)=0"; SQLParameter param = new SQLParameter(); param.addParam(userpk); param.addParam(pk_corp); Set<String> currolepks = (Set<String>) SHYCProxy.getUAPQueryBS().executeQuery(sql, param ,new HashSetColumnProcessor()); //5.查询登录用户绑定的角色为空则不进行提醒 if(YCPubUtils.isEmpty(currolepks)){ return false; } //当前登录用户的所有角色,将存在于集合A中的但不存在于集合B中的元素移除 currolepks.retainAll(rolepkSet); return currolepks.size() > 0; }catch(Exception e){ Logger.error(e.getMessage(),e); throw new BusinessException("参数格式有误,请检查公司级参数YX220!"); } 优化点: 1. 将注释与代码分离,让代码更加清晰易读。 2. 使用currolepks.retainAll(rolepkSet)代替手动遍历移除元素,提高代码简洁性和性能。 3. 减少if语句嵌套,提高代码可读性。 4. 将异常捕获和处理放到try-catch块中,提高代码健壮性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值