我正在尝试引用BOOK的TITLE和AUTHOR元素,同时使用for-each循环遍历每个SHELF。 这是我的XML:
<DOC>
<BOOKS>
<BOOK ID="1234">
<TITLE>Intro to XSLT</TITLE>
<AUTHOR>Junior Writer</AUTHOR>
</BOOK>
<BOOK ID="1235">
<TITLE>Advanced XSLT</TITLE>
<AUTHOR>Senior Writer</AUTHOR>
</BOOK>
</BOOKS>
<CABINET>
<SHELF>
<NAME>Top</NAME>
<BOOK ID="1234"/>
<BOOK ID="1235"/>
</SHELF>
<SHELF>
<NAME>Middle</NAME>
<BOOK ID="1235"/>
</SHELF>
</CABINET>
</DOC>
在黑暗中拍摄了许多变化之后,我正在尝试使用当前的XSL但是没有工作:
<xsl:for-each select="CABINET/SHELF">
<xsl:value-of select="NAME"> Shelf:
<xsl:for-each select="BOOK">
<xsl:value-of select="/BOOKS/BOOK[@ID=current()/@ID]/TITLE"/> by
<xsl:value-of select="/BOOKS/BOOK[@ID=current()/@ID]/AUTHOR"/>
</xsl:for-each>
</xsl:for-each>
我希望它显示为:
Top Shelf:
Intro to XSLT by
Junior Writer
Advanced XSLT by
Senior Writer
Middle Shelf:
Advanced XSLT by
Senior Writer
答案 0 :(得分:0)
我对你的例子感到有些困惑。首先,您的XML输入不是well-formed;你没有一个根元素。此外,在您的XSLT代码段中,您选择DOCUMENT
元素,但输入中不存在该元素。 (更不用说你错过了所有=
属性的select
。)
否则,您使用current()
比较ID
属性的方法是正确的,并且可行。
另一种选择是使用a key。
以下是两种方式的示例。如果您仍然无法将这些应用于实际的XML,请更新问题中的XML,我可以更新我的答案。
XML输入(已更新为格式良好)
<DOC>
<BOOKS>
<BOOK ID="1234">
<TITLE>Intro to XSLT</TITLE>
<AUTHOR>Junior Writer</AUTHOR>
</BOOK>
<BOOK ID="1235">
<TITLE>Advanced XSLT</TITLE>
<AUTHOR>Senior Writer</AUTHOR>
</BOOK>
</BOOKS>
<CABINET>
<SHELF>
<NAME>Top</NAME>
<BOOK ID="1234"/>
<BOOK ID="1235"/>
</SHELF>
<SHELF>
<NAME>Middle</NAME>
<BOOK ID="1235"/>
</SHELF>
</CABINET>
</DOC>
选项#1 (fiddle)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:for-each select="CABINET/SHELF">
<xsl:if test="position() > 1"><xsl:text>

</xsl:text></xsl:if>
<xsl:value-of select="NAME"/>
<xsl:text> Shelf:
</xsl:text>
<xsl:for-each select="BOOK">
<xsl:if test="position() > 1"><xsl:text>
</xsl:text></xsl:if>
<xsl:value-of select="/DOC/BOOKS/BOOK[@ID = current()/@ID]/TITLE"/>
<xsl:text> by
</xsl:text>
<xsl:value-of
select="/DOC/BOOKS/BOOK[@ID = current()/@ID]/AUTHOR"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
选项#2 (fiddle)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="books" match="BOOK" use="@ID"/>
<xsl:template match="/*">
<xsl:for-each select="CABINET/SHELF">
<xsl:if test="position() > 1"><xsl:text>

</xsl:text></xsl:if>
<xsl:value-of select="NAME"/>
<xsl:text> Shelf:
</xsl:text>
<xsl:for-each select="BOOK">
<xsl:if test="position() > 1"><xsl:text>
</xsl:text></xsl:if>
<xsl:value-of select="key('books',@ID)/TITLE"/>
<xsl:text> by
</xsl:text>
<xsl:value-of select="key('books',@ID)/AUTHOR"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这两个选项都会产生以下输出:
Top Shelf:
Intro to XSLT by
Junior Writer
Advanced XSLT by
Senior Writer
Middle Shelf:
Advanced XSLT by
Senior Writer
你也可以使用push-style而不是pull-style,这样如果/当它变得更复杂时,你的样式表会更容易扩展...
选项#2推送式(fiddle)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="books" match="BOOK" use="@ID"/>
<xsl:template match="/DOC">
<xsl:apply-templates select="CABINET/SHELF"/>
</xsl:template>
<xsl:template match="SHELF[position() > 1]">
<xsl:text>

</xsl:text>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="NAME">
<xsl:apply-templates/>
<xsl:text> Shelf:</xsl:text>
</xsl:template>
<xsl:template match="BOOK">
<xsl:text>
</xsl:text>
<xsl:apply-templates select="key('books',@ID)/TITLE"/>
<xsl:text> by
</xsl:text>
<xsl:apply-templates select="key('books',@ID)/AUTHOR"/>
</xsl:template>
</xsl:stylesheet>