Избегайте оператора //
. У него, как правило, не самые лучшие характеристики, особенно когда вы вкладываете его так, как делаете (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>
Еще лучше объявить ключ XSL:
<xsl:key name="kAuthorById" match="author" use="@id" />
и доступ к нему с помощью функции key()
:
<xsl:value-of select="key('kAuthorById', authorID)/name" />
Этот метод обладает лучшими показателями, особенно когда входные документы становятся больше.
Вам также следует избегать <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>