XSLT存档  

不及格的程序员-八神

 查看分类:  ASP.NET XML/XSLT JavaScripT   我的MSN空间Blog

 

JavaX

作者 主题: 设计模式:递归与分组 IP地址:
八神

[过客]
发表于: 8/25/2005 1:34:55 AM 编辑 删掉

递归:

编写一个递归模板,将整个列表作为参数传给它.如果列表不为空,则处理它的第一项,然后递归调用自身来处理列表除第一项以外的其余部分.

  例子: 计算总销售额

  数据文件
    <booklist>
       <book>
          <title>Angela's Ashes</title>
          <author>Frank McCourt</author>
          <publisher>HarperCollins</publisher>
          <isbn>0 00 649840 X</isbn>
          <price>6.99</price>
          <sales>235</sales>
       </book>
       <book>
          <title>Sword of Honour</title>
          <author>Evelyn Waugh</author>
          <publisher>Penguin Books</publisher>
          <isbn>0 14 018967 X</isbn>
          <price>12.99</price>
          <sales>12</sales>
       </book>
    </booklist>

  样式表
  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template name="total-sales-value">
        <xsl:param name="list"/>
        <xsl:choose>
            <xsl:when test="$list">
                <xsl:variable name="first" select="$list[1]"/>
                <xsl:variable name="total-of-rest">
                    <xsl:call-templates name="total-sales-value">
                        <xsl:with-param name="list" select="$list[position()!=1]"/>
                    </xsl:call-templates>
                </xsl:variable>
                <xsl:value-of select=" $first/sales * $first/price + $total-of-rest"/>
            </xsl:when>
            <xsl:otherwise>0</xsl:otherwise>
        </xsl:choose>
    </xsl:template>
  </xsl:stylesheet>


数据分组:

数据文件

<cities>
   <city name="Paris" country="France"/>
   <city name="Roma" country="Italia"/>
   <city name="Nice" country="France"/>
   <city name="Madrid" country="Espana"/>
   <city name="Milano" country="Italia"/>
   <city name="Firenze" country="Italia"/>
   <city name="Napoli" country="Italia"/>
   <city name="Lyon" country="France"/>
   <city name="Barcelona" country="Espana"/>
</cities>

普通排序,特点速度慢.慢指数为 N*(N-1)/2次

样式表1

<xsl:stylesheet   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   
<xsl:output indent="yes"/>
   
<xsl:template match="/">
  <xsl:variable name="unique-countries"   
       select="/cities/city[not(@country=preceding-sibling::city/@country)]/@country" />
  <countries>
    <xsl:for-each select="$unique-countries">
      <country name="{.}">
        <xsl:for-each select="//city[@country=current()]">
          <city>
            <xsl:value-of select="@name"/>
          </city>
        </xsl:for-each>
      </country>
    </xsl:for-each>
  </countries>
</xsl:template>

</xsl:stylesheet>

另一种  样式表2

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
   
<xsl:output indent="yes"/>
   
<xsl:template match="/">

  <xsl:variable name="sorted-cities">
    <xsl:for-each select="//city">    
      <xsl:sort select="@country"/>    
      <xsl:copy-of select="."/>  
    </xsl:for-each>
  </xsl:variable>
  
  <xsl:variable name="unique-countries" select="$sorted-cities/city[not(@country=preceding-sibling::city[1]/@country)]/@country" />
  <countries>   
    <xsl:for-each select="$unique-countries">      
      <country name="{.}">         
        <xsl:for-each select="$sorted-cities/city[@country=current()]">            
          <city><xsl:value-of select="@name"/></city>         
        </xsl:for-each>      
      </country>   
    </xsl:for-each>
  </countries>
</xsl:template>

</xsl:stylesheet>

Muenchian 分组技术 它来自 Oracle.

样式表3

<xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   version="1.1">
   
<xsl:output indent="yes"/>

<xsl:key name="country-key" match="city" use="@country"/>
   
<xsl:template match="/">

  <xsl:variable name="unique-countries"   
    select="/cities           
            /city[generate-id(.)=                 
              generate-id(key('country-key', @country))]/@country" />
  
  <countries>   
    <xsl:for-each select="$unique-countries">      
      <country name="{.}">         
        <xsl:for-each select="key('country-key', .)">            
          <city><xsl:value-of select="@name"/></city>         
        </xsl:for-each>      
      </country>   
    </xsl:for-each>
  </countries>
</xsl:template>

</xsl:stylesheet>

此留言被版主修改于:8/25/2005 2:59:34 AM


 
性别: 男  

作者 主题: 表达式 IP地址:
八神

[过客]
发表于: 8/22/2005 1:13:13 AM 编辑 删掉

p287;

表达式[$A=$B=$C]是合法的,然而这并不是很有用,有时可能会出乎我们所期望的结果.
它等价于[($A=$B)=$C],即测试$C经转换为布尔值以后,与$A和$B进行比较的结果再进行比较.
例如:[2=1=0]为真,这是因为,[2=1]为假,0转换为bool值为假,因此...

比较节点集

节点节$N与字符串'mary'进行比较时,如果$N中有一节点n满足:string-value(n)='mary',则我们说

[$N='mary'];同理,如果$N中有一节点n满足:string-value(n)!='mary',则我们说[$N!='mary'].如果$N中有两

个节点,其字符串分别为mary和john,则[$N='mary']、[$N!='mary']将同时成立,如果$N为空节点,结果将都为假

,$N=$N也为假.

注意:我们所说的节点集中的节点,考虑的仅仅是节点集中的成员,不包括子节点.

属性与字符串的比较

例如,要比较{xsl:if test="@name != 'james'"}与{xsl:if test="not(@name='james')"}是否等价,可以看出,

如果name属性不存在,第一个表达式结果为假,而第二个表达式结果为真.

测试当前节点的父节点是否是根节点的较好方法是使用{parent::*[not(..)]},它对于那些有父节点但没有祖父

节点来说为真.还可以用{generate-id(..)=generate-id(/)}来比较节点集的任一个单独的成员,另外,当且仅当

父节点与根节点是同一节点时,{count(..|/) and ..}为真,其中 and 条件是必要的,因为如果去掉它,对于没有

父了点的节点(即根节点),上述表达式同样成立.


 
性别: 男  

作者 主题: = 运算符 IP地址:
八神

[过客]
发表于: 8/19/2005 5:21:55 AM 编辑 删掉

不能认为[$X=$X]始终为真,如果$X为空节点集时,它将为假。
不能认为[$X!=3]等价于[not($X=3)],当$X为节点集时,只要有一个节点的节点值不为3,第一个表达式就为真;而当节点集中所有的节点值都不为3时第二个表达式才为真。
不能认为如果[$X=$Y and $Y=$Z],则[$X=$Z],仍以节点集为例,两个节点集相等只要它们有相同的节点值即可,因此{2,3}={3,4}为真,且{3,4}={4,5}为真,但{2,3}={4,5}为假。


 
性别: 男  

作者 主题: 比较运算符//与/descendant:: IP地址:
八神

[过客]
发表于: 8/18/2005 11:24:17 PM 编辑 删掉

//X为/descendant-or-self::node()/X的简写。
//ele[1]将选择任何一个(全部的)ele做为其父元素的第一个子元素的节点。如果想要选择第一个ele元素,应该这样写:/descendant::ele[1] 或者 (//ele)[1]。


 
性别: 男  

作者 主题: 何时集合不是一个集合? IP地址:
八神

[过客]
发表于: 8/15/2005 4:28:53 AM 编辑 删掉

样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
 
 <xsl:output method="text" />

 <xsl:variable name="a" select="/Root/Numbers[1]/Integer/@value"/> 
 <xsl:variable name="b" select="/Root/Numbers[1]/Integer/@value[. > 2]"/> 
 <xsl:variable name="c" select="/Root/Numbers[1]/Integer/@value[. = 3]"/> 

 <xsl:template match="/">
 
 SET A: { <xsl:for-each select="$a"> <xsl:value-of select="." />, </xsl:for-each> }
 SET B: { <xsl:for-each select="$b"> <xsl:value-of select="." />, </xsl:for-each> }
 SET C: { <xsl:for-each select="$c"> <xsl:value-of select="." />, </xsl:for-each> }

  a UNION b:  { <xsl:for-each select="$a | $b"> <xsl:value-of select="." 
/>, </xsl:for-each> }
  b UNION c:  { <xsl:for-each select="$b | $c"> <xsl:value-of select="." 
/>, </xsl:for-each> }
  a INTERSECTION b:  { <xsl:for-each select="$a[count(.|$b) = count($b)]"> 
<xsl:value-of select="." />, </xsl:for-each> }
  a INTERSECTION c:  { <xsl:for-each select="$a[count(.|$c) = count($c)]"> 
<xsl:value-of select="." />, </xsl:for-each> }
  a DIFFERENCE b:  { <xsl:for-each select="$a[count(.|$b) != count($b)] | 
$b[count(.|$a) != count($a)]"> <xsl:value-of select="." />, </xsl:for-each> }
  a DIFFERENCE c:  { <xsl:for-each select="$a[count(.|$c) != count($c)] | 
$c[count(.|$a) != count($a)]"> <xsl:value-of select="." />, </xsl:for-each> }
  a SUBSET OF b:  { <xsl:value-of select="count($b | $a) = count($b)"/> }
  b SUBSET OF a:  { <xsl:value-of select="count($b | $a) = count($a)"/> }
 
 </xsl:template>

</xsl:stylesheet>
输出
  SET A: { 4, 2, 3,  }
  SET B: { 4, 3,  }
  SET C: { 3,  }

  a UNION b:  { 4, 2, 3,  }
  b UNION c:  { 4, 3,  }
  a INTERSECTION b:  { 4, 3,  }
  a INTERSECTION c:  { 3,  }
  a DIFFERENCE b:  { 2,  }
  a DIFFERENCE c:  { 4, 2,  }
  a SUBSET OF b:  { false }
  b SUBSET OF a:  { true }

此留言被版主修改于:8/15/2005 4:33:21 AM


 
性别: 男  

作者 主题: 集合 IP地址:
八神

[过客]
发表于: 8/15/2005 3:43:23 AM 编辑 删掉

XSLT程序员参考手册(Michael Kay)189页;
<xsl:key name="book-author" match="book" use="author/name"/>

如果需要查找两个关键字的交集,可以写下面的令人费解的表达式:
<xsl:variable name="set1" select="key('book-author','Alex Homer')"/>
<xsl:variable name="set2" select="key('book-author','David Sussman')"/>
<xsl:variable name="result" select="$set1[count(.|$set2)=count($set2)]"/>

上述代码是可行的,因为如果X是Y的子集,则count(X|Y)等效于count(Y)。
因此其中的谓词过滤掉了$se1中的内容,而仅仅选择了$set2中的元素。

359页 关于count()函数的介绍:
要检查上下文节点是否是节点集$special中的一个节点,可以这样
<xsl:if test="count(.|$special)=count($special)">
</xsl:if>


 
性别: 男  

作者 主题: 标旗位|位标记(Bit Flag) IP地址:
八神

[过客]
发表于: 8/9/2005 5:00:11 AM 编辑 删掉

开发人员通常要用到位标记. 

什么是位标记? 
    就是在二进制数的上1的位置是都是不同,这样我们可以用&或|位运算符来完成某些功能. 

位标记是什么样的? 
   
 声明几个常量为文件属性: 

    ReadOnly = 0x0001; //0000 0001 
    Hidden = 0x0002; //0000 0010 
    System = 0x0004; //0000 0100 
    Directory= 0x0010; //0000 1000 
... 

如何使用位标记? 
return ReadOnly & Hidden; // result = 3; 0000 0011 
return System | Directory....

此留言被版主修改于:8/9/2005 5:06:10 AM


 
性别: 男 
XSLT current() 函数
XSLT 函数参考对象 完整的 XSLT 函数参考对象
定义和用法
current() 函数返回仅包含当前节点的节点集。通常,当前节点与上下文节点是相同的。

<xsl:value-of select="current()"/>

等于

<xsl:value-of select="."/>

不过,有一点不同。让我们看一下下面的 XPath 表达式:"catalog/cd"。表达式选择了当前节点的 <catalog> 子节点,然后选择了 <catalog> 节点的 <cd> 子节点。这意味着,在计算的每一步上,"." 都有不同的意义。

下面这行:

<xsl:apply-templates select="//cd[@title=current()/@ref]"/>

将处理 title 属性的值等于当前节点的 ref 属性的值的所有 cd 元素。

与这个不同:

<xsl:apply-templates select="//cd[@title=./@ref]"/>

这个会处理 title 属性和 ref 属性具有相同值的所有 cd 元素。

 

posted on 2015-05-14 20:39  不及格的程序员-八神  阅读(10)  评论(0编辑  收藏  举报