• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            流量統(tǒng)計(jì):
            Rixu Blog (日需博客)
            日需博客,每日必需來(lái)踩踩哦..
            posts - 108,comments - 54,trackbacks - 0

            大家說(shuō)我說(shuō)的跟.net一點(diǎn)關(guān)系都沒(méi)有,可是第一篇我也說(shuō)了啊,僅僅是一個(gè)HELLO的例子啊。現(xiàn)在哪個(gè)人不忙啊。只能一點(diǎn)一點(diǎn)的寫(xiě)了。。

            好了,廢話(huà)少說(shuō),我們先看看實(shí)際的情況,然后根據(jù)情況來(lái)寫(xiě)一個(gè)小小的例子吧,這次有Demo下載嘍。。。

            現(xiàn)實(shí)項(xiàng)目中的情況:

            現(xiàn)實(shí)的項(xiàng)目中,我們不可能是有著一堆的XML的,這些XML有可能一部分是來(lái)自于現(xiàn)有的文檔,有一部分可能是從其它服務(wù)提供者那里得到的,當(dāng)然也有可能是自己寫(xiě)的服務(wù)提供的……

            總之一句話(huà),不到真正開(kāi)始了,天曉得xml是哪里來(lái)的。

            現(xiàn)實(shí)很殘酷,我們也很聰明,辦法總是有的,而且非常簡(jiǎn)單,這里我建立了一個(gè)Index.xml,一個(gè)Index.xslt文件放到網(wǎng)站的Album目錄中:

            可以通過(guò)一個(gè)配置文檔來(lái)配置所有XML的URL,從而增進(jìn)可維護(hù)性。

            Index.xml文件的內(nèi)容:

            <?xml version="1.0" encoding="utf-8" ?>
            <?xml-stylesheet type="text/xsl" href="Index.xslt"?>
            <services>
            <album>XML FILE URL</album>
            </services>

            Index.xslt文件的內(nèi)容:

            <?xml version="1.0" encoding="utf-8"?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
            <xsl:output method="html" indent="yes" doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/>
            <xsl:template match="services">
            <html xmlns="http://www.w3.org/1999/xhtml">
            <head>
            <title>Index</title>
            </head>
            <body>
            <h1>
            <xsl:value-of select="album"/>
            </h1>
            </body>
            </html>
            </xsl:template>
            </xsl:stylesheet>

            當(dāng)確認(rèn)上述兩敗個(gè)文檔都正確建立后,再建立一個(gè)Index.ashx文件,用于提供XML數(shù)據(jù),并且將Index.xml文件的album元素的值改為Index.ashx的URL。

            public void ProcessRequest(HttpContext context)
            {
            context.Response.ContentType = "text/xml";
            context.Response.ContentEncoding = Encoding.UTF8;
            List<Album> albums = new AlbumBusiness().Select("ArtistId=1");
            XmlSerializer albumXmlSerializer = new XmlSerializer(albums.GetType(), new XmlRootAttribute("Albums"));
            albumXmlSerializer.Serialize(context.Response.OutputStream, albums);
            }

            準(zhǔn)備工作都做好了,看看輸出的XML大致的樣式吧:

            <?xml version="1.0"?>
            <Albums xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <Album>
            <AlbumId>386</AlbumId>
            <GenreId>1</GenreId>
            <ArtistId>1</ArtistId>
            <Title>For Those About To Rock We Salute You</Title>
            <Price>8.99</Price>
            <AlbumArtUrl>/Content/Images/placeholder.gif</AlbumArtUrl>
            </Album>
            <Album>
            <AlbumId>387</AlbumId>
            <GenreId>1</GenreId>
            <ArtistId>1</ArtistId>
            <Title>Let There Be Rock</Title>
            <Price>8.99</Price>
            <AlbumArtUrl>/Content/Images/placeholder.gif</AlbumArtUrl>
            </Album>
            </Albums>

            XSL通過(guò)variable標(biāo)記聲明變量。

            這里要說(shuō)到xsl和變量和函數(shù)了,將下面的內(nèi)容添加到Index.xslt文檔的template下面:

            <xsl:variable name="AlbumServiceUrl" select="album"></xsl:variable>
            <xsl:variable name="Albums" select="document($AlbumServiceUrl)/Albums/Album"></xsl:variable>

            xsl:variable 標(biāo)記用于聲明變量。其name屬性用于指定此變量的名稱(chēng),select屬性用于選擇變量的內(nèi)容,在這里不難看出,它是選擇了services節(jié)點(diǎn)下的album節(jié)點(diǎn)的值。這里使用的是相對(duì)path。其文檔來(lái)源由所在的template來(lái)決定。

            Albums變量的select中使用了document函數(shù),此函數(shù)使用一個(gè)文檔路徑的參數(shù)來(lái)載入一個(gè)xml文檔。其后面跟著的“/Albums/Album” XPpath指定了選擇我們指定的那個(gè)文檔下面所有的Album節(jié)點(diǎn)存放在此變量中。

            在XSL中,引用變量的方式是在變量名前面加一個(gè)$符號(hào)。

            如上面的$AlbumServiceUrl.

            接下來(lái)要輸出些東西了,我們還要再看一個(gè)新的XSL標(biāo)記:xsl:for-each:

            <ul>
            <xsl:for-each select="$Albums">
            <li>
            <xsl:value-of select="Title"/>
            </li>
            </xsl:for-each>
            </ul>

            前面已經(jīng)說(shuō)過(guò),我們是把所有Album節(jié)點(diǎn)都存到了Albums變量中了,那么這里也應(yīng)當(dāng)很容易看得出我們是在遍歷所有Album節(jié)點(diǎn),然后把其子元素Title的值以li的形式輸出。再加上最外面包圍的一個(gè)ul,整個(gè)一個(gè)無(wú)序列表就出來(lái)了。

            這里無(wú)需編譯,可以直接運(yùn)行Index.xml以查看結(jié)果,我們可以把這些內(nèi)容直接返還給客戶(hù)端。樣式表(xslt)文件因?yàn)槭庆o態(tài)的,所以客戶(hù)端只需要下載一次既可,可以暫時(shí)認(rèn)為和css文件類(lèi)似,只是其功能側(cè)重點(diǎn)不同而已。

            我想,看到這里,你一定會(huì)想到,如果做分布式的話(huà),xslt確實(shí)可以給出不錯(cuò)的解決方案。

            問(wèn)題像是已經(jīng)都解決了。但由于返回的只是xml和xslt文檔,加上搜索引擎對(duì)xml和xslt支持并不怎么樣,還可能有一些瀏覽器根本不支持xslt的情況,那么就要用到服務(wù)器端的編譯了:

            再建立一個(gè)Transform.ashx文件:

            public void ProcessRequest(HttpContext context)
            {
            context.Response.ContentType = "text/html";
            context.Response.ContentEncoding = Encoding.UTF8;

            string xmlUrl = context.Server.MapPath(@"Index.xml");
            string xsltUrl = context.Server.MapPath(@"Index.xslt");
            XslCompiledTransform trans = new XslCompiledTransform();
            trans.Load(xsltUrl, new XsltSettings() { EnableDocumentFunction = true, EnableScript = true }, new XmlUrlResolver());
            trans.Transform(xmlUrl, null, context.Response.OutputStream);
            }

            還有一個(gè)問(wèn)題就是怎么知道是蜘蛛訪問(wèn)的還是用戶(hù)訪問(wèn)的呢?目前我是使用的檢查UserAgent里面的值。之前在XSLT 入門(mén)--實(shí)際應(yīng)用中使用的是排除蜘蛛的方式,這里要使用排除已知支持XSLT的瀏覽器的方式:

            在web.config中appSettings節(jié)點(diǎn)下加入如下值:

            <add key="XsltSupportBrowsers" value="Chrome|MSIE 9.0"/>

            然后將Transform.ashx中ProcessRequest方法更改如下:

            public void ProcessRequest(HttpContext context)
            {
            context.Response.ContentType = "text/html";
            context.Response.ContentEncoding = Encoding.UTF8;

            string[] xsltSupportBrowsers = ConfigurationManager.AppSettings["XsltSupportBrowsers"].Split('|');
            foreach (var xsltSupportBrowser in xsltSupportBrowsers)
            {
            if (context.Request.UserAgent.Contains(xsltSupportBrowser))
            {
            context.Response.ContentType = "text/xml";
            context.Response.WriteFile(context.Server.MapPath("Index.xml"));
             return;
            }
            }

            string xmlUrl = context.Server.MapPath(@"Index.xml");
            string xsltUrl = context.Server.MapPath(@"Index.xslt");
            XslCompiledTransform trans = new XslCompiledTransform();
            trans.Load(xsltUrl, new XsltSettings() { EnableDocumentFunction = true, EnableScript = true }, new XmlUrlResolver());
            trans.Transform(xmlUrl, null, context.Response.OutputStream);
            }

            Index.xml文件和Index.xslt文件的路徑是固定的,不會(huì)改變的,可以直接寫(xiě)。

            通過(guò)httpHandlers配置節(jié)點(diǎn)將請(qǐng)求映射到處理程序。

            那么我們也可以把所有請(qǐng)求都交給一個(gè)Handler來(lái)處理,xslt和xml文件我們都放到同一個(gè)目錄的情況下可以這樣做:

            在httpHandlers配置節(jié)點(diǎn)中加入一條配置,將所有對(duì).xhtml文件的請(qǐng)求都交給我們的Transform Handler來(lái)處理:

            <add verb="*" path="*.xhtml" type="MusicStore.Web.Albums.Transform"/>

            .ashx文檔(一般處理程序)可大大簡(jiǎn)化xslt的實(shí)施。

            然后將Transform.ashx中ProcessRequest方法也可以再次更改成通用的方式,在這里沒(méi)有做異常處理,因?yàn)閮H僅是為了說(shuō)明能這樣做:

            public void ProcessRequest(HttpContext context)
            {
            context.Response.ContentType = "text/html";
            context.Response.ContentEncoding = Encoding.UTF8;
            string requestPhysicalPath = context.Request.PhysicalPath;
            string requestFileName = requestPhysicalPath.Substring(0, requestPhysicalPath.LastIndexOf("."));
            string xmlUrl = requestFileName + ".xml";
            string xsltUrl = requestFileName + ".xslt";
            string[] xsltSupportBrowsers = ConfigurationManager.AppSettings["XsltSupportBrowsers"].Split('|');
            foreach (var xsltSupportBrowser in xsltSupportBrowsers)
            {
            if (context.Request.UserAgent.Contains(xsltSupportBrowser))
            {
            context.Response.ContentType = "text/xml";
            context.Response.WriteFile(xmlUrl);
            return;
            }
            }
            XslCompiledTransform trans = new XslCompiledTransform();
            trans.Load(xsltUrl, new XsltSettings() { EnableDocumentFunction = true, EnableScript = true }, new XmlUrlResolver());
            trans.Transform(xmlUrl, null, context.Response.OutputStream);
            }

            都搞定了,不過(guò)還有個(gè)問(wèn)題還是現(xiàn)在說(shuō)一下吧,那就是不是所有時(shí)候我們都愿意把所有的內(nèi)容都寫(xiě)到一個(gè)xslt中。例如:網(wǎng)站的頁(yè)頭和頁(yè)腳難道每個(gè)XSLT文件中都復(fù)制粘貼一份?這里再建立一個(gè)Albums.xslt來(lái)解決這個(gè)問(wèn)題:

            可以通過(guò)指定xslt模板的name屬性來(lái)聲明一個(gè)可訪問(wèn)的xslt模板。

            <?xml version="1.0" encoding="utf-8"?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
            <xsl:output method="html" indent="yes"/>
            <xsl:template name="Albums" match="album">
            <xsl:variable name="AlbumServiceUrl" select="album"></xsl:variable>
            <xsl:variable name="Albums" select="document($AlbumServiceUrl)/Albums/Album"></xsl:variable>
            <ul>
            <xsl:for-each select="$Albums">
            <li>
            <xsl:value-of select="Title"/>
            </li>
            </xsl:for-each>
            </ul>
            </xsl:template>
            </xsl:stylesheet>

            這里最主要的是使用了template的name屬性,也就是給模板起個(gè)名字。可以先認(rèn)為就像.net里的服務(wù)器控件,給它起個(gè)ID就可以訪問(wèn)。但性質(zhì)是完全不同的。

            call-template標(biāo)記通過(guò)name屬性指定模板名稱(chēng)來(lái)調(diào)用xslt模板。

            調(diào)用xslt模板的方式也有多種:

            這里使用<xsl:call-template />標(biāo)記:

            <xsl:call-template name="Albums" />

            由于我們將此模板放到了Albums.xslt文件中,而不是在當(dāng)前文檔中,所以得使用另一個(gè)標(biāo)記來(lái)引入外部的xslt文件,

            Import標(biāo)記通過(guò)href屬性指定xslt URL來(lái)引入外部XSLT文件。

            將此標(biāo)記放到Index.xslt文檔的output標(biāo)記之前:

            <xsl:import href="Albums.xslt"/>


            此時(shí)再將Index.xslt中的變量聲明與ul下的所有內(nèi)容注釋或刪除。仍然可以得到想要的結(jié)果。

            下載此項(xiàng)目源代碼


            Logo
            作者:Gezidan
            出處:http://www.rixu.net    
            本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。

            本文轉(zhuǎn)載自 http://www.cnblogs.com/javennie/archive/2011/09/28/xsltinaspnet.html
            posted on 2011-09-28 10:33 日需博客 閱讀(439) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C#技術(shù)文章轉(zhuǎn)載
            久久影院综合精品| 狠狠色丁香久久综合婷婷| 国产亚洲美女精品久久久久狼| 久久午夜福利无码1000合集| 久久久久久精品免费免费自慰| 久久精品亚洲AV久久久无码| 亚洲国产精品无码久久SM | 国产精品乱码久久久久久软件 | 91精品国产乱码久久久久久| 亚洲国产精品久久久久婷婷软件 | 久久久久亚洲Av无码专| 无码任你躁久久久久久| 久久精品国内一区二区三区| 婷婷久久综合九色综合九七| 久久久噜噜噜久久熟女AA片| 久久五月精品中文字幕| 日本久久久精品中文字幕| 99国产欧美久久久精品蜜芽| 日韩亚洲国产综合久久久| 99久久er这里只有精品18| 久久久这里只有精品加勒比 | 亚洲国产日韩欧美久久| 久久午夜电影网| 久久99热这里只有精品国产| 久久久久国产视频电影| 久久国产三级无码一区二区| 久久久av波多野一区二区| 久久久亚洲裙底偷窥综合| 欧美精品福利视频一区二区三区久久久精品| 亚洲精品乱码久久久久久蜜桃图片| 久久久久久久久久免免费精品| 热99re久久国超精品首页| 狠狠88综合久久久久综合网| 99久久99久久精品国产片果冻| 无码人妻精品一区二区三区久久| 久久亚洲国产精品123区| 久久高清一级毛片| 中文字幕精品久久久久人妻| 精品综合久久久久久88小说| 久久久久国产一区二区| 久久久午夜精品福利内容|