关于 xml:XSLT 显示功绩徽章的问题

XSLT trouble with displaying merit badges

我在尝试显示 1 名侦察员的所有功绩徽章时遇到了麻烦……而且我想不出一个可行的解决方案。例如,我希望它像这样显示(带换行符):

1
2
3
4
First Aid
Swimming
Life saving
...

到目前为止,它只显示每个侦察兵的第一个,即急救

这是 XML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?xml version ="1.0" encoding ="utf-8"?>
<!DOCTYPE bsa SYSTEM"assign08.dtd">
<?xml-stylesheet type="text/xsl" href="assign08.xsl"?>
<bsa>
  <council name ="jedi">
    <troop number ="01" unitname="ok">
  <scout>
    <firstname>John</firstname>
    <lastname>Smith</lastname>
    <phone>111-111-1111</phone>
   
      <street>Fork St.</street>
      <city>Portland</city>
      <state>OR</state>
      </address>
    <rank date-earned ="1/1/01">Eagle</rank>
    <meritbadge date-earned ="1/1/00">First Aid</meritbadge>
    <meritbadge date-earned ="2/1/00">Swimming</meritbadge>
    <meritbadge date-earned ="3/1/00">Life Saving</meritbadge>
    <meritbadge date-earned ="4/1/00">Environmental Science</meritbadge>
    <meritbadge date-earned ="5/1/00">Camping</meritbadge>
    <meritbadge date-earned ="6/1/00">Cooking</meritbadge>
    <meritbadge date-earned ="7/1/00">Safety</meritbadge>
    <meritbadge date-earned ="8/1/00">Basket Weaving</meritbadge>
    <meritbadge date-earned ="9/1/00">Wood carving</meritbadge>
    <meritbadge date-earned ="10/1/00">Archery</meritbadge>
    </scout>
  <scout>
    <firstname>Bill</firstname>
    <lastname>Joel</lastname>
    <phone>111-111-1112</phone>
   
      <street>Fork St.</street>
      <city>Portland</city>
      <state>OR</state>
      </address>
    <rank date-earned ="2/2/02">Eagle</rank>
    <meritbadge date-earned ="1/1/00">First Aid</meritbadge>
    <meritbadge date-earned ="2/1/00">Swimming</meritbadge>
    <meritbadge date-earned ="3/1/00">Life Saving</meritbadge>
    <meritbadge date-earned ="4/1/00">Environmental Science</meritbadge>
    <meritbadge date-earned ="5/1/00">Camping</meritbadge>
    <meritbadge date-earned ="6/1/00">Cooking</meritbadge>
    <meritbadge date-earned ="7/1/00">Safety</meritbadge>
    <meritbadge date-earned ="8/1/00">Basket Weaving</meritbadge>
    <meritbadge date-earned ="9/1/00">Wood carving</meritbadge>
    <meritbadge date-earned ="10/1/00">Archery</meritbadge>
    </scout>

...

这里是 XSL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="UTF-8"?>

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

 <xsl:template match="/">
<html>
<body>
Buy Scouts of America
<table border="1">
 <tr bgcolor="#9acd32">
   <th>Last Name</th>
     <th>First Name</th>
   <th>Phone Number</th>
     <th>Address</th>
     <th>Rank</th>
     <th>Merit Badges</th>
 </tr>
 <xsl:for-each select="bsa/council/troop/scout">
  <xsl:sort select="lastname"/>
 <tr>
   <td><xsl:value-of select="lastname"/></td>
     <td><xsl:value-of select="firstname"/></td>
   <td><xsl:value-of select="phone"/></td>
     <td><xsl:value-of select="address"/></td>
     <td><xsl:value-of select="rank"/></td>
     <td><xsl:value-of select="meritbadge"/></td>
 </tr>
 </xsl:for-each>
  </table>
  </body>
 </html>
</xsl:template>

</xsl:stylesheet>

这是因为您使用的是 XSLT 1.0 和 xsl:value-of。在 1.0 中,xsl:value-of 只会给你第一次出现的值。

尝试使用 <xsl:apply-templates select="meritbadge"/> 代替。如果您需要更改输出的格式,请添加一个与 meritbadge 匹配的模板,并按您喜欢的格式设置。示例:

1
2
3
4
<xsl:template match="meritbadge">
    <xsl:value-of select="."/>
    <br/>
</xsl:template>

另外(不相关)你有"购买美国童子军"而不是"美国童子军"。

EDIT - 修改后的 XSLT 的完整示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <html>
            <body>
                Buy Scouts of America
                <table border="1">
                    <tr bgcolor="#9acd32">
                        <th>Last Name</th>
                        <th>First Name</th>
                        <th>Phone Number</th>
                        <th>Address</th>
                        <th>Rank</th>
                        <th>Merit Badges</th>
                    </tr>
                    <xsl:for-each select="bsa/council/troop/scout">
                        <xsl:sort select="lastname"/>
                        <tr>
                            <td><xsl:value-of select="lastname"/></td>
                            <td><xsl:value-of select="firstname"/></td>
                            <td><xsl:value-of select="phone"/></td>
                            <td><xsl:value-of select="address"/></td>
                            <td><xsl:value-of select="rank"/></td>
                            <td><xsl:apply-templates select="meritbadge"/></td>
                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="meritbadge">
        <xsl:value-of select="."/>
        <br/>
    </xsl:template>

</xsl:stylesheet>

编辑 #2 - 独立的议会/部队

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/*">
        <html>
            <body>
                Boy Scouts of America
                <xsl:apply-templates select="council"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="council">
        <xsl:value-of select="@name"/>
        <xsl:apply-templates select="troop"/>
    </xsl:template>

    <xsl:template match="troop">
        <xsl:value-of select="concat(@number,' - ',@unitname)"/>
        <table border="1">
            <tr bgcolor="#9acd32">
                <th>Last Name</th>
                <th>First Name</th>
                <th>Phone Number</th>
                <th>Address</th>
                <th>Rank</th>
                <th>Merit Badges</th>
            </tr>
            <xsl:apply-templates select="scout">
                <xsl:sort select="lastname"/>
            </xsl:apply-templates>
        </table>
    </xsl:template>

    <xsl:template match="scout">
        <tr>
            <td><xsl:apply-templates select="lastname"/></td>
            <td><xsl:apply-templates select="firstname"/></td>
            <td><xsl:apply-templates select="phone"/></td>
            <td><xsl:apply-templates select="address"/></td>
            <td><xsl:apply-templates select="rank"/></td>
            <td><xsl:apply-templates select="meritbadge"/></td>
        </tr>
    </xsl:template>

    <xsl:template match="meritbadge|address/*">
        <xsl:value-of select="."/>
        <br/>
    </xsl:template>

</xsl:stylesheet>