在XSLT谓词中使用XML元素值

0 xml xslt

我不完全确定这是否可能与XSLT和我的讲师不知道我在说什么,所以如果有人可以帮助,谢谢!

我有一个XML文件,其中包含一个作者列表,每个作者都有一个唯一的ID,还有一个书籍列表,每个书籍都有一个IDREF作为其值的子元素.该文件的布局如下:

<library>
  <authors>
    <author id="a001">
       <name>Joyce</name>
    </author>
  </authors>
  <books>
    <book id="b001">
      <name>Illiad</name>
      <authorID>a001</authorID>
    </book>
  </books>
</library>
Run Code Online (Sandbox Code Playgroud)

我正在尝试写出所有书籍的列表,并使用authorID值获取有关作者的信息.

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
Run Code Online (Sandbox Code Playgroud)

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>XSLT Test</title>
</head>

<body>
    <xsl:for-each select="//book">
     <div style="display:block; background-color:#999; padding:2px; margin:2px;">
         <h2><xsl:value-of select="name"/></h2>
            <p><xsl:value-of select="synopsis"/></p>
            <ul>
             <li>Author: <xsl:value-of select="//author[@id='X']/name"/></li>
            </ul>
        </div>
    </xsl:for-each>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

通过用一个值(例如a001)替换X,我可以恢复Joyce但是如何在此处使用authorID值,以便系统可以很好地扩展?

Tom*_*lak 6

避免//操作员.它往往没有最好的性能特征,特别是当你像你那样嵌套它时(for-each //, value-of //).

使用规范的XPath表达式,像这样.他们表现得更好:

<xsl:for-each select="/library/books/book">
  <div style="display:block; background-color:#999; padding:2px; margin:2px;">
    <h2><xsl:value-of select="name"/></h2>
    <p><xsl:value-of select="synopsis"/></p>
    <ul>
      <li>
        <xsl:text>Author: </xsl:text>
        <!-- use the current() function to access the current node (book) -->
        <xsl:value-of select="
          /library/authors/author[@id=current()/authorID]/name
        "/>
      </li>
    </ul>
  </div>
</xsl:for-each>
Run Code Online (Sandbox Code Playgroud)

更好的是,声明一个XSL密钥:

<xsl:key name="kAuthorById" match="author" use="@id" />
Run Code Online (Sandbox Code Playgroud)

并使用以下key()功能访问它:

<xsl:value-of select="key('kAuthorById', authorID)/name" />
Run Code Online (Sandbox Code Playgroud)

到目前为止,这种方法具有最佳性能,特别是当输入文档变大时.

你也应该避免<xsl:for-each>.尝试编写模板并使用模板匹配:

<xsl:template match="library">
  <body>
    <xsl:apply-templates select="books" />
  </body>
</xsl:template>

<xsl:template match="books">
  <h1>List of Books</h1>
  <xsl:apply-templates select="book" />
</xsl:template>

<xsl:template match="book">
  <div style="display:block; background-color:#999; padding:2px; margin:2px;">
    <h2><xsl:value-of select="name"/></h2>
    <p><xsl:value-of select="synopsis"/></p>
    <ul>
      <li>Author: <xsl:value-of select="key('kAuthorById', authorID)/name"/></li>
    </ul>
    </div>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)