为什么是xsl:什么时候没有按预期工作?

时间:2015-03-06 14:28:34

标签: xml xslt xslt-2.0

我是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>

2 个答案:

答案 0 :(得分:2)

注意:确定您的输入XML在给定XSLT的情况下生成显示输出的内容真的是一个不必要的挑战。请在下次问题中包含输入内容。

说明:当您的模板与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>

答案 1 :(得分:1)

  

如果可能,您可以展示我们如何在中实现此预期输出   XSL:选择

要使用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轴)和自身。与您的尝试不同的是,对source的孩子进行了测试,如果source任何孩子为<bold>,则第一次测试会返回true。

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