为什么 xsl:when 没有按预期工作?

Why is xsl:when not working as expected?

我是 XSLT 的初学者,我对如何使用有点困惑 xsl:when。请在下面找到我的示例 XSLT 代码以及预期输出和我从 XSLT 获得的实际输出。您能否提出您的解决方案并解释我在使用 xsl:when.

时做错了什么

XML

<source>
  <bold>Hello, world.</bold>
  <italic>fine.</italic>
  <red>I am </red>
</source>

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="source">
            <xsl:choose>
                <xsl:when test="bold">
                    <xsl:element name="p">
                        <xsl:element name="b">
                        <xsl:value-of select="bold"></xsl:value-of>
                    </xsl:element>
                    </xsl:element>
                </xsl:when>
                <xsl:when test="red">
                    <xsl:element name="p">
                        <xsl:value-of select="red"></xsl:value-of>
                    </xsl:element>
                </xsl:when>
                <xsl:when test="italic">
                    <xsl:element name="p">
                        <xsl:element name="i">
                            <xsl:value-of select="italic"></xsl:value-of>
                        </xsl:element>
                    </xsl:element>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:element name="p">
                        <xsl:apply-templates/>
                    </xsl:element>
                </xsl:otherwise>
            </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

预期输出

<p><b>Hello, world.</b></p>
<p><i>fine.</i></p>
<p style="color:red;">I am </p>

实际输出

<p><b>Hello, world.</b></p>

注意: 考虑到您的 XSLT,弄清楚您的输入 XML 会产生显示的输出是一个不必要的挑战,真的。下次请在您的问题中包含输入。

说明: 当您的模板匹配 source 元素时,xsl:choose 仅找到第一个测试通过的 xsl:when 条件。一个更好的组织来实现你想要的输出将把 xsl:when 元素分解成它们自己的 xsl:templates...

给定此输入 XML:

<source>
  <bold>Hello, world.</bold>
  <italic>fine.</italic>
  <red>I am </red>
</source>

此 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">

  <xsl:output omit-xml-declaration="yes"/>

  <xsl:template match="bold">
    <p><b><xsl:apply-templates/></b></p>
  </xsl:template>

  <xsl:template match="red">
    <p style="color:red;"><xsl:apply-templates/></p>
  </xsl:template>

  <xsl:template match="italic">
    <p><i><xsl:apply-templates/></i></p>
  </xsl:template>

</xsl:stylesheet>

将产生请求的输出:

  <p><b>Hello, world.</b></p>
  <p><i>fine.</i></p>
  <p style="color:red;">I am </p>

但是你真的应该添加这个额外的模板:

  <xsl:template match="source">
    <div><xsl:apply-templates/></div>
  </xsl:template>

要生成格式正确的输出 XML:

<div>
  <p><b>Hello, world.</b></p>
  <p><i>fine.</i></p>
  <p style="color:red;">I am </p>
</div>

If possible can you show how we can Implement this expected output in xsl:choose?

要使用 xsl:choose 实现此功能,您可以执行以下操作:

<xsl:template match="source">
    <div>
        <xsl:apply-templates/>
    </div>
</xsl:template>

<xsl:template match="source/*">
    <xsl:choose>
        <xsl:when test="self::bold">
            <p><b><xsl:apply-templates/></b></p>
        </xsl:when>
        <xsl:when test="self::italic">
            <p><i><xsl:apply-templates/></i></p>
        </xsl:when>
        <xsl:when test="self::red">
            <p style="color:red;"><xsl:apply-templates/></p>
        </xsl:when>
        <xsl:otherwise>
            <p><xsl:apply-templates/></p>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

请注意,此处使用 xsl:choose 的模板与 source 的实际子元素匹配 - 与您在父级 source 级别进行的尝试不同。

这意味着每个元素都测试自己(因此使用 self 轴)并且只测试自己。与您的尝试不同,如果 sourceany 子项是 <bold>.[=20,则测试 source 的子项并在第一次测试中返回 true =]

请记住,仅仅因为它是可能的,并不意味着它是最好的方法。