利用XSLT产生一个唯一的ID并引用它

Generating Unique IDs and Linking to Them

When an XSLT stylesheet converts one XML document into another, the ability to add unique ID values to elements in the result document can make the result document much more useful to applications that use it. Adding unique IDs can, for example, turn each element into the unique target of a link.

XSLT's generate-id() function generates a unique ID for a node passed to it as an argument. This ID starts with a letter so that you can use it as the value of an XML ID attribute. For example, the following stylesheet copies an XML document and adds a uid ("unique ID") attribute to each chapter, sect1, and sect2 element. The xsl:value-of instruction uses the generate-id() function in the stylesheet's first template rule to create a value for these attributes.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version=
"1.0"><xsl:output method="xml" omit-xml-declaration="yes"/>
  <xsl:template match="chapter | sect1 | sect2">
    <xsl:copy>
      <xsl:attribute name="uid">
        <xsl:value-of select="generate-id(.)"/>
      </xsl:attribute>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

The stylesheet turns this XML document

<chapter>
<para>Then with expanded wings he steers his flight</para>
<figure><title>"Incumbent on the Dusky Air"</title>
<graphic fileref="pic1.jpg"/></figure>
<para>Aloft, incumbent on the dusky Air</para>
<sect1>
<para>That felt unusual weight, till on dry Land</para>
<figure><title>"He Lights"</title>
<graphic fileref="pic2.jpg"/></figure>
<para>He lights, if it were Land that ever burned</para>
<sect2>
<para>With solid, as the Lake with liquid fire</para>
<figure><title>"The Lake with Liquid Fire"</title>
<graphic fileref="pic3.jpg"/></figure>
</sect2>
</sect1>
</chapter>
into this one:

<chapter uid="N134711680">
<para>Then with expanded wings he steers his flight</para>
<figure><title>"Incumbent on the Dusky Air"</title>
<graphic fileref="pic1.jpg"/></figure>
<para>Aloft, incumbent on the dusky Air</para>
<sect1 uid="N134683456">
<para>That felt unusual weight, till on dry Land</para>
<figure><title>"He Lights"</title>
<graphic fileref="pic2.jpg"/></figure>
<para>He lights, if it were Land that ever burned</para>
<sect2 uid="N134684064">
<para>With solid, as the Lake with liquid fire</para>
<figure><title>"The Lake with Liquid Fire"</title>
<graphic fileref="pic3.jpg"/></figure>
</sect2>
</sect1>
</chapter>

Your XSLT processor may generate different values with the generate-id() function. In fact, if you run the same stylesheet with the same input document a second time, the XSLT processor may not generate the same ID values that it generated the first time. However, if you call generate-id() more than once in one run with the same node as an argument, it generates the same ID value each time for that node. Because unique IDs are popular ways to identify link destinations, this consistency of the generate-id() function makes it a great way to generate links.

For example, adding a list of all of its illustrations at the beginning of the result document. If we make the result tree version an HTML file, we can use the generate-id function to turn each entry of this opening illustration list into an HTML link to the img element in the body of the document that has the illustration:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0">
  <xsl:output method="html"/>
  <xsl:template match="chapter">
    <html><body>
      <!-- Generate a list of picture titles, with each 
           title linking to the picture in the poem below. -->
      <b>Pictures:</b><br/>
      <xsl:for-each select="descendant::figure">
        <a href="#{generate-id(graphic)}">
        <xsl:value-of select="title"/></a><br/>
    </xsl:for-each>
    <xsl:apply-templates/>
    </body></html>
  </xsl:template>
  <xsl:template match="para">
    <p><xsl:apply-templates/></p>
  </xsl:template>
  <xsl:template match="graphic">
    <!-- Image and title as caption, centered. -->
    <center><a name="{generate-id(.)}"><img src="{@fileref}"/></a>
    <b><xsl:value-of select="../title"/></b></center>
  </xsl:template>
  <!-- Suppress figure title because "graphic" template
       rule already added it to result tree. -->
  <xsl:template match="figure/title"/>
</xsl:stylesheet>

With the source document above, this stylesheet creates the following HTML document:

<html>
    <body>
        <b>Pictures:</b>
        <br>
        <a href="#N134691840">"Incumbent on the Dusky Air"</a>
        <br>
        <a href="#N134692416">"He Lights"</a>
        <br>
        <a href="#N134757920">"The Lake with Liquid Fire"</a>
        <br>
<p>Then with expanded wings he steers his flight</p>
<center>
            <a name="N134691840"><img src="pic1.jpg"></a>
            <b>"Incumbent on the Dusky Air"</b>
        </center>
<p>Aloft, incumbent on the dusky Air</p>
<p>That felt unusual weight, till on dry Land</p>
<center>
            <a name="N134692416"><img src="pic2.jpg"></a>
            <b>"He Lights"</b>
        </center>
<p>He lights, if it were Land that ever burned</p>
<p>With solid, as the Lake with liquid fire</p>
<center>
            <a name="N134757920"><img src="pic3.jpg"></a>
            <b>"The Lake with Liquid Fire"</b>
        </center>

</body>
</html>

(To view the HTML document, you'll need to supply your own pic1.jpg, pic2.jpg, and pic3.jpg files.) The stylesheet uses the generate-id() ID twice:

This consistency in the generate-id() function's treatment of a particular node, even if the function generates an ID for that node more than once, is the key to its power. These graphic elements didn't have IDs in the source document; with the help of this function, their equivalent in the result document has them, and other elements in that document use those IDs to link to them.

XSLT(XML Stylesheet Language Transformations)中,你可以利用它将XML文档转换成其他形式,比如HTML、CSV等。如果你想要对多个数据项求总分,通常你需要创建一个计算节点,例如`<xsl:value-of>`或`<xsl:sum>`,并使用XPath表达式来选择需要相加的数据。 假设你有如下的XML结构,每个`<score>`元素代表一个分数: ```xml <students> <student id="1"> <subject>Math</subject> <score>85</score> </student> <student id="2"> <subject>Science</subject> <score>90</score> </student> <!-- 更多学生... --> </students> ``` 你可以编写如下的XSLT脚本来计算所有学生的数学和科学总分: ```xsl <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <!-- 对于每个科目,求所有学生的分数之和 --> <xsl:template match="/"> <xsl:text>Total Math Score: </xsl:text> <xsl:variable name="mathTotal"> <xsl:apply-templates select="//student[subject='Math']/score"/> </xsl:variable> <xsl:value-of select="$mathTotal"/>, <xsl:text>Total Science Score: </xsl:text> <xsl:variable name="scienceTotal"> <xsl:apply-templates select="//student[subject='Science']/score"/> </xsl:variable> <xsl:value-of select="$scienceTotal"/> </xsl:template> <!-- 计算单个分数 --> <xsl:template match="score"> <xsl:if test="@subject = 'Math' or @subject = 'Science'"> <xsl:value-of select="."/> <xsl:if test="position() != last()"> + </xsl:if> </xsl:if> </xsl:template> </xsl:stylesheet> ``` 运行这个XSLT,你会得到每个科目的总分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值