来自以下xml数据:
<lieferungen>
<artikel id="1111">
<name>apfel</name>
<preis stueckpreis="true">8.97</preis>
<lieferant>Fa. Krause</lieferant>
</artikel>
<artikel id="7866">
<name>Kirschen</name>
<preis stueckpreis="false">10.45</preis>
<lieferant>Fa. Helbig</lieferant>
</artikel>
<artikel id="3526">
<name>apfel</name>
<preis stueckpreis="true">12.67</preis>
<lieferant>Fa. Liebig</lieferant>
</artikel>
<artikel id="7866">
<name>Kirschen</name>
<preis stueckpreis="false">17.67</preis>
<lieferant>Fa. Krause</lieferant>
</artikel>
<artikel id="3526">
<name>apfel</name>
<preis stueckpreis="true">9.54</preis>
<lieferant>Fa. Mertes</lieferant>
</artikel>
<artikel id="7866">
<name>Kirschen</name>
<preis stueckpreis="false">16.45</preis>
<lieferant>Fa. Hoeller</lieferant>
</artikel>
<artikel id="7868">
<name>Kohl</name>
<preis stueckpreis="false">3.20</preis>
<lieferant>Fa. Hoeller</lieferant>
</artikel>
<artikel id="7866">
<name>Kirschen</name>
<preis stueckpreis="false">12.45</preis>
<lieferant>Fa. Richard</lieferant>
</artikel>
<artikel id="3245">
<name>Bananen</name>
<preis stueckpreis="false">15.67</preis>
<lieferant>Fa. Hoeller</lieferant>
</artikel>
<artikel id="6745">
<name>Kohl</name>
<preis stueckpreis="false">3.10</preis>
<lieferant>Fa. Reinhardt</lieferant>
</artikel>
<artikel id="7789">
<name>Ananas</name>
<preis stueckpreis="true">8.60</preis>
<lieferant>Fa. Richard</lieferant>
</artikel>
</lieferungen>
我想通过xslt创建以下输出:
Fa. Helbig supplies: Kirschen
Fa. Liebig supplies: apfel
Fa. Krause supplies: apfel Kirschen
Fa. Mertes supplies: apfel
Fa. Hoeller supplies: Kirschen Kohl Bananen
Fa. Reinhardt supplies: Kohl
Fa. Richard supplies: Kirschen Ananas
为此,我编写了以下xslt代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="lieferungen">
<html>
<head>
<title>
<xsl:text>Lieferanten</xsl:text>
</title>
</head>
<body bgcolor="#ffffff">
<h1>
<xsl:text>Suppliers</xsl:text>
</h1>
<hr/>
<xsl:apply-templates select="//lieferant"></xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="lieferant">
<p>
<xsl:value-of select="text()"/>
<xsl:text> supplies: </xsl:text>
<xsl:for-each select="//artikel[lieferant/text() = current()/text()]">
<xsl:value-of select="name/text()"/>
<xsl:text></xsl:text>
</xsl:for-each>
</p>
</xsl:template>
</xsl:stylesheet>
这给了我以下输出:
Fa. Krause supplies: apfelKirschen
Fa. Helbig supplies: Kirschen
Fa. Liebig supplies: apfel
Fa. Krause supplies: apfelKirschen
Fa. Mertes supplies: apfel
Fa. Hoeller supplies: KirschenKohlBananen
Fa. Hoeller supplies: KirschenKohlBananen
Fa. Richard supplies: KirschenAnanas
Fa. Hoeller supplies: KirschenKohlBananen
Fa. Reinhardt supplies: Kohl
Fa. Richard supplies: KirschenAnanas
为了摆脱重复,我改变了xslt-code如下(注意标记修改/添加的两行的注释):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<!--THE FOLLOWING LINE OF CODE WAS ADDED (CHANGE 1/2): -->
<xsl:key name="suppliers" match="lieferant" use="lieferant" />
<xsl:template match="lieferungen">
<html>
<head>
<title>
<xsl:text>Lieferanten</xsl:text>
</title>
</head>
<body bgcolor="#ffffff">
<h1>
<xsl:text>Suppliers</xsl:text>
</h1>
<hr/>
<!--THE FOLLOWING LINE OF CODE WAS MODIFIED (CHANGE 2/2):-->
<xsl:apply-templates select="//lieferant[generate-id()=generate-id(key('suppliers', lieferant)[1])]"></xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="lieferant">
<p>
<xsl:value-of select="text()"/>
<xsl:text> supplies: </xsl:text>
<xsl:for-each select="//artikel[lieferant/text() = current()/text()]">
<xsl:value-of select="name/text()"/>
<xsl:text></xsl:text>
</xsl:for-each>
</p>
</xsl:template>
</xsl:stylesheet>
然而,这打破了代码。我使用的代码有什么问题?
答案 0 :(得分:2)
您想要的输出可以通过以下方式实现:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/lieferungen">
<html>
<head>
<title>Lieferanten</title>
</head>
<body>
<h1>Suppliers</h1>
<hr/>
<xsl:for-each-group select="artikel" group-by="lieferant">
<p>
<xsl:value-of select="current-grouping-key()"/>
<xsl:text> supplies: </xsl:text>
<xsl:value-of select="current-group()/name"/>
</p>
</xsl:for-each-group>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
如果您使用的是样式表版本所示的XSLT 2.0处理器,请参阅michael.hor257k的回答。否则,这是你的样式表出了什么问题...
在您更改代码的两个地方,上下文为lieferant
,但您尝试使用子lieferant
的值。在您的来源中,lieferant
没有孩子lieferant
。
例如,在您的xsl:键中,您选择lieferant
并使用lieferant
。如果您要use
选择相同的节点,请使用.
。
使用key()
时也是如此;它在lieferant
的谓词中使用,因此要使用该上下文使用.
。
这是您更新的XSLT。我在你所做的相同位置修改了它,但是在xsl:text中添加了一个空格来分隔name
。我添加了一条注释,指出此更改以保持一致。
我做的另一件事是将版本更改为1.0并删除未使用的xs
命名空间声明。 (这个样式表的输出中没有真正改变任何内容。)
更新了XSLT 1.0
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--THE FOLLOWING LINE OF CODE WAS ADDED (CHANGE 1/3): -->
<xsl:key name="suppliers" match="lieferant" use="." />
<xsl:template match="lieferungen">
<html>
<head>
<title>
<xsl:text>Lieferanten</xsl:text>
</title>
</head>
<body bgcolor="#ffffff">
<h1>
<xsl:text>Suppliers</xsl:text>
</h1>
<hr/>
<!--THE FOLLOWING LINE OF CODE WAS MODIFIED (CHANGE 2/3):-->
<xsl:apply-templates
select="//lieferant[generate-id()=generate-id(key('suppliers', .)[1])]"/>
</body>
</html>
</xsl:template>
<xsl:template match="lieferant">
<p>
<xsl:value-of select="text()"/>
<xsl:text> supplies: </xsl:text>
<xsl:for-each select="//artikel[lieferant/text() = current()/text()]">
<xsl:value-of select="name/text()"/>
<!--THE FOLLOWING LINE OF CODE WAS MODIFIED (CHANGE 3/3):-->
<xsl:text> </xsl:text>
</xsl:for-each>
</p>
</xsl:template>
</xsl:stylesheet>
<强>更新强>
就像Michael在评论中提到的那样,你使用<xsl:for-each select="//artikel[lieferant/text() = current()/text()]">
失去了Muenchian分组的一半好处。
我建议您创建一个在artikel
级别选择并使用lieferant
作为密钥的密钥。
示例(带有注释以指示所有更改)...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--THE FOLLOWING LINE OF CODE WAS ADDED (CHANGE 1/7): -->
<xsl:key name="suppliers" match="artikel" use="lieferant" />
<xsl:template match="lieferungen">
<html>
<head>
<title>
<xsl:text>Lieferanten</xsl:text>
</title>
</head>
<body bgcolor="#ffffff">
<h1>
<xsl:text>Suppliers</xsl:text>
</h1>
<hr/>
<!--THE FOLLOWING LINE OF CODE WAS MODIFIED (CHANGE 2/7):-->
<xsl:apply-templates
select="//artikel[generate-id()=generate-id(key('suppliers', lieferant)[1])]"/>
</body>
</html>
</xsl:template>
<!--THE FOLLOWING LINE OF CODE WAS MODIFIED (CHANGE 3/7):-->
<xsl:template match="artikel">
<p>
<!--THE FOLLOWING LINE OF CODE WAS MODIFIED (CHANGE 4/7):-->
<xsl:value-of select="lieferant"/>
<xsl:text> supplies: </xsl:text>
<!--THE FOLLOWING LINE OF CODE WAS MODIFIED (CHANGE 5/7):-->
<xsl:for-each select="key('suppliers',lieferant)">
<!--THE FOLLOWING LINE OF CODE WAS MODIFIED (CHANGE 6/7):-->
<xsl:value-of select="name"/>
<!--THE FOLLOWING LINE OF CODE WAS MODIFIED (CHANGE 7/7):-->
<xsl:text> </xsl:text>
</xsl:for-each>
</p>
</xsl:template>
</xsl:stylesheet>
但是,你可以修改xsl:for-each:
<xsl:for-each select="key('suppliers',.)">
<xsl:value-of select="../name"/>
<xsl:text> </xsl:text>
</xsl:for-each>