假设我正在将多项选择测验从任意XML格式转换为HTML。每个选项都将在结果文档中表示为HTML <li>
标记。对于每个选项,如果该选项是正确答案,我想向class
添加correct
<li>
的HTML submitted
。此外,如果该选项是用户选择的选项,我想向<li>
添加<li>
类。因此,如果选择的是以及正确的,那么class
应该correct submitted
<p>Who trained Obi-Wan Kenobi?</p>
<ul>
<li>Mace Windu</li>
<li class="correct submitted">Qui-Gon Jinn</li>
<li>Ki-Adi-Mundi</li>
<li>Yaddle</li>
</ul>
。
据我所知,空格分隔的属性值不是XML数据模型的一部分,因此无法通过XSLT直接创建。但是,我觉得有一种更好的方法,比为每个可能的类组合使用一个条件(在本例中可以接受,但在更复杂的场景中难以处理)乱丢代码。
如何以优雅的方式解决这个问题?
所需结果示例:
{{1}}
答案 0 :(得分:10)
首先,XML中的属性值中的空格没有任何问题:粗略地说,attribute value normalization将空白字符转换为空格,并在解析文档时将相邻空格折叠到单个空格,但绝对允许空格。 编辑:有关详情,请参阅下文。
Matthew Wilson的方法未能在可能的值之间包含空格,正如您在评论中提到的那样。然而,他的方法基本上是合理的。拼图的最后一部分是你不喜欢冗余空间:这些可以通过使用normalize-space
XPath函数来消除。
以下样式表将所有位放在一起 - 请注意,它不会对其输入文档执行任何操作,因此出于测试目的,您可以针对任何XML文档运行它,甚至可以针对自身运行它,以验证输出是否符合您的要求要求。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="foo0" select="false()"/>
<xsl:variable name="bar0" select="true()"/>
<xsl:variable name="foo1" select="true()"/>
<xsl:variable name="bar1" select="false()"/>
<xsl:variable name="foo2" select="true()"/>
<xsl:variable name="bar2" select="true()"/>
<xsl:template match="/">
<xsl:variable name="foobar0">
<xsl:if test="$foo0"> foo</xsl:if>
<xsl:if test="$bar0"> bar</xsl:if>
</xsl:variable>
<xsl:variable name="foobar1">
<xsl:if test="$foo1"> foo</xsl:if>
<xsl:if test="$bar1"> bar</xsl:if>
</xsl:variable>
<xsl:variable name="foobar2">
<xsl:if test="$foo2"> foo</xsl:if>
<xsl:if test="$bar2"> bar</xsl:if>
</xsl:variable>
<li>
<xsl:attribute name="class">
<xsl:value-of select="normalize-space($foobar0)"/>
</xsl:attribute>
</li>
<li>
<xsl:attribute name="class">
<xsl:value-of select="normalize-space($foobar1)"/>
</xsl:attribute>
</li>
<li>
<xsl:attribute name="class">
<xsl:value-of select="normalize-space($foobar2)"/>
</xsl:attribute>
</li>
</xsl:template>
</xsl:stylesheet>
编辑:除了在属性值中分隔离散组件的空格问题之外:XML Spec将许多可能的有效构造定义为attribute types,包括IDREFS和NMTOKENS。第一种情况与Names制作相匹配,第二种情况与NMTokens制作相匹配;这两个产品都被定义为包含多个适当类型的值,由空格分隔。因此,以空格分隔的值列表作为单个属性的值是XML信息集的固有组件。
答案 1 :(得分:5)
在我的脑海中,您可以构建一个以空格分隔的列表,其中包含:
<li>
<xsl:attribute name="class">
<xsl:if cond="...">correct</xsl:if>
<xsl:if cond="...">submitted</xsl:if>
</xsl:attribute>
</li>
答案 2 :(得分:1)
据我所知,空格分隔的属性值不是XML数据模型的一部分,因此无法通过XSLT直接创建
除非您要转换为XML语言(HTML不是,XHTML),否则您不必担心XSLT 输出的XML有效性。这可以是任何东西,也不需要符合XML!