2

我正在使用 XSLT 1.0 处理具有以下示例结构的 xml 文档:

<root>
    <descriptions>
        <description name="abc">
            <detail>XXXXXXXXXXXXX</detail>
        </description>
        <description name="def">
            <detail>XXXXXXXXXXXXX</detail>
        </description>
        <description name="ghi">
            <detail>XXXXXXXXXXXXX</detail>
        </description>
        <description name="lmn">
            <detail>XXXXXXXXXXXXX</detail>
        </description>
        // ....... several more description elements
    </descriptions>

    <list>
        <book name="abc"/>
        <book name="def"/>
        <book name="lmn"/>
    </list>
</root> 

我希望使用'name'属性将'list'节点下的'book'与'descriptions'下的'description'相匹配。所以输出会是这样的:

abc
XXXXXXXXXXXXX

def
XXXXXXXXXXXXX

lmn
XXXXXXXXXXXXX

我试过:

<?xml version="1.0" encoding="ISO-8859-1"?>

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

<xsl:for-each select="root/list/book">
    <xsl:param name="bookName" select="@name"/>
    <xsl:for-each select="root/descriptions/description">
        <xsl:if test="$bookName = @name">
            <h3><xsl:value-of select="$bookName"/></h3>
            <p><xsl:value-of select="detail"/></p>
        </xsl:if>
    </xsl:for-each>
</xsl:for-each>
</xsl:stylesheet>

我认为必须有一种比使用嵌套 for-each 更有效的方法来实现这一点,但我想不出一个..那么有人可以给我一些帮助吗?谢谢!!

4

1 回答 1

2

您可以使用更简洁且可能更高效的谓词(取决于您的 XSLT 处理器):

<xsl:for-each select="root/list/book">
    <xsl:param name="bookName" select="@name"/>
    <xsl:variable name="desc"
          select="/root/descriptions/description[@name = $bookName]" />
    <h3><xsl:value-of select="$bookName"/></h3>
    <p><xsl:value-of select="$desc/detail"/></p>
</xsl:for-each>

要获得更大的效率改进,请使用密钥。例如把这个声明放在后面<xsl:output>

<xsl:key name="descriptions-by-name" match="description" use="@name" />

然后更改<xsl:variable> select属性以使用密钥:

    <xsl:variable name="desc"
          select="key('descriptions-by-name', $bookName)" />
于 2013-05-30T21:03:36.637 回答