使用 XSLT 以每行三列的形式显示 XML 数据



我有以下XML数据,我想在其中以每行三列显示食谱。我想在 td 中显示食谱标签的标题、服务和图像节点,每行 3 个 td,并在下一行中按照搜索的食谱进行操作。

<recipeList>
    <recipe id="ch02_recipe020">
        <title>Spinach and zucchini frittata</title>
        <serves>Serves 4</serves>
        <ingredientList>
            <ingredientEntry>
                <ingredientQty>1 tablespoon</ingredientQty>
                <keyIngredient>olive oil</keyIngredient>
            </ingredientEntry>
            <ingredientEntry>
                <ingredientQty>1</ingredientQty>
                <keyIngredient>red onion</keyIngredient>, thinly sliced
            </ingredientEntry>
        </ingredientList>
        <prepSteps>
            <prepStep>
                <para>Heat the oil in a medium non-stick frying pan and fry the onion and zucchini over medium heat until they are a pale golden brown. Add the garlic and cook it for a minute. Add the spinach and cook until the spinach has wilted and any excess moisture has evaporated off — if you don't do this, your frittata will end up soggy in the middle, as the liquid will continue to come out as it cooks. Shake the pan so you get an even layer of mixture. Turn the heat down to low.</para>
            </prepStep>
        </prepSteps>
        <figure>
            <img src="images/01075/091.jpg" />
        </figure>
    </recipe>
    <recipe id="ch02_recipe026">
        <title>Bacon and avocado salad</title>
        <serves>Serves 4</serves>
        <ingredientList>
            <ingredientEntry>
                <ingredientQty>8</ingredientQty>
                <keyIngredient>bacon rashers</keyIngredient>, rinds cut off
            </ingredientEntry>
        </ingredientList>
        <prepSteps>
            <prepStep>
                <para>Turn on the grill (broiler). Put the bacon on a tray and grill on both sides until it is nice and crisp. Leave it to cool and then break into pieces.</para>
            </prepStep>
            <prepStep>
                <para>Bring a saucepan of water to the boil and cook the beans for 4 minutes. Drain and then hold them under cold running water for a few seconds to stop them cooking any further.</para>
            </prepStep>
        </prepSteps>
        <figure>
            <img src="images/01075/103.jpg" />
        </figure>
    </recipe>
    <recipe id="ch02_recipe028">
        <title>Spinach salad with chicken and sesame dressing</title>
        <serves>Serves 4</serves>
        <ingredientList>
            <ingredientEntry>
                <ingredientQty>450 g (1 lb)</ingredientQty>
                <keyIngredient>baby English spinach leaves</keyIngredient>
            </ingredientEntry>
            <ingredientEntry>
                <ingredientQty>1</ingredientQty>
                <keyIngredient>Lebanese (short) cucumber</keyIngredient>, peeled and diced
            </ingredientEntry>
        </ingredientList>
        <prepSteps>
            <prepStep>
                <para>Put the spinach in a large bowl. Scatter the cucumber, spring onion and carrot over the top. Shred the chicken breast into long pieces and scatter it over the vegetables.</para>
            </prepStep>
        </prepSteps>
        <figure>
            <img src="images/01075/107.jpg" />
        </figure>
        <file src="MB Pages/Lunch.qxd" />
    </recipe>
    <recipe id="ch03_recipe025">
        <title>Tandoori chicken with cardamom rice</title>
        <serves>Serves 4</serves>
        <ingredientList>
            <ingredientEntry>
                <ingredientQty>250 ml (1 cup)</ingredientQty>
                <keyIngredient>natural yoghurt</keyIngredient>, plus extra for serving
            </ingredientEntry>
        </ingredientList>
        <prepSteps>
            <prepStep>
                <para>Soak eight wooden skewers in water for 30 minutes to prevent them burning during cooking. Combine the yoghurt, tandoori paste and lemon juice in a non-metallic dish. Add the chicken and coat well, then cover and marinate for at least 10 minutes.</para>
            </prepStep>
        </prepSteps>
        <figure>
            <img src="images/01075/174.jpg" />
        </figure>
        <file src="MB Pages/Casual 124-185.qxd" />
    </recipe>
</recipeList>

我正在使用下面的 XSLT,但它没有每行显示 3 条记录。

<?xml version="1.0" encoding="UTF-8" ?>
<!-- Designed by SoftServ Solutions, February 13, 2017 -->
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:m="http://www.w3.org/1998/Math/MathML"
                xmlns:xlink="http://www.w3.org/1999/xlink">
    <xsl:output method="html" indent="yes" encoding="windows-1252" />
    <xsl:preserve-space elements="*" />
    <xsl:template match="/">
        <html>
        <head>
            <title>Murdoch Books DIY</title>
        </head>
        <body>
            <xsl:apply-templates select="recipeList" />
        </body>
    </html>
</xsl:template>
<xsl:output indent="yes" />
<xsl:strip-space elements="*" />
<xsl:param name="cols">3</xsl:param> <!-- set the number of rows here -->
<xsl:template match="recipeList">
    <table width="30%" align="center" border="1">
        <xsl:apply-templates select="recipe[position() mod $cols = 1 or position() = 1]" mode="row" />
    </table>
</xsl:template>
<xsl:template match="recipe" mode="row">
    <tr>
        <xsl:apply-templates select=". | following-sibling::title[position() &lt; $cols]" mode="cell" />
    </tr>
</xsl:template>
<xsl:template match="recipe" mode="cell">
    <td>
        <xsl:value-of select="title" />
        <xsl:value-of select="serves" />
        <br />
        <xsl:if test="figure">
            <xsl:apply-templates select="figure" />
        </xsl:if>
    </td>
</xsl:template>
<xsl:template match="figure">
    <p align="left">
        <img width="25%" height="25%">
        <xsl:attribute name="src">
            <xsl:value-of select="img/@src" />
        </xsl:attribute>
        </img>
    </p>
    <a>
        <xsl:attribute name="name">
            <xsl:value-of select="@id" />
        </xsl:attribute>
    </a>
    <p>
        <xsl:apply-templates select="caption" />
    </p>
    <p>
        <xsl:apply-templates select="source" />
    </p>
</xsl:template>
</xsl:stylesheet>

谁能帮忙?我是 XSLT 的新手。

您需要更改此部分:

<xsl:template match="recipe" mode="row">
    <tr>
        <xsl:apply-templates select=". | following-sibling::title[position() &lt; $cols]" mode="cell" />
    </tr>
</xsl:template>

自:

<xsl:template match="recipe" mode="row">
    <tr>
        <xsl:apply-templates select=". | following-sibling::recipe[position() &lt; $cols]" mode="cell" />
    </tr>
</xsl:template>

当您使用它时,您可以在此处删除冗余:

<xsl:apply-templates select="recipe[position() mod $cols = 1 or position() = 1]" mode="row" />

并简单地使其:

<xsl:apply-templates select="recipe[position() mod $cols = 1]" mode="row" />

您还有两个xsl:output元素,<xsl:preserve-space elements="*" />xsl:strip-space elements="*" />,这几乎没有意义。这些只是我注意到的几件事,可能还有更多。

最新更新