2009-10-26 27 views
6

假设我正在将任意XML格式的多选测验转换为HTML。每个选项都将在结果文档中以HTML <li>标签表示。对于每个选项,如果该选择是正确的答案,我想要将correct的HTML class添加到<li>。此外,如果该选择是用户选择的选项,我想在<li>中添加一类submitted。因此,如果所提交的以及的选择是正确的,那么<li>应具有的correct submitted是否有一种使用XSLT添加多个HTML类的优雅方式?

据我所知,空格分隔的属性值不是XML数据模型的一部分,因此不能直接通过XSLT创建。然而,我觉得有一种更好的方法可以做到这一点,而不是为每个可能的类组合使用一个条件(这在本例中是可以接受的,但在更复杂的情况下难以使用)。

如何以优雅的方式解决此问题?期望结果的

例子:

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

回答

9

首先,XML中的属性值中的空格没有问题:粗略地说,attribute value normalization在分析文档时将空格字符转换为空格并将相邻空格折叠为单个空格,但肯定允许空格。 编辑:关于这方面的更多信息,请参阅下文。

马修威尔逊的方法没有在可能的值之间加入空格,正如你在你的评论中提到的那样。但是,他的方法基本上是合理的。拼图的最后一部分是你不喜欢多余的空间:这些可以通过使用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规范的一些可能的有效构建体定义为attribute types,包括IDREFS和NMTOKENS。第一个案例匹配Names生产,第二个案例匹配NMTokens生产;这两个制作都被定义为包含由空格分隔的适当类型的多个值。因此,空格分隔的值列表作为单个属性的值是XML信息集的固有组件。

+0

实际上,我关于空白分隔的属性值的观点是,XML无法将它们识别为不同的值 - 它都是一个长字符串(除非我忽略了XML的某个部分)。这就是我在开始使用类属性时总是感觉有点脏的原因。也就是说,我意识到在我们的编码器中,只需将空间中的类与空间中的类分开,而不是在各处添加一堆''子元素即可。 – Jakob 2009-10-26 21:36:30

+2

@Jakob:我在回复结尾处添加了一些关于空格分隔的值列表的详细信息,这些值构成了一个属性值。 – NickFitz 2009-10-27 10:36:45

5

关闭我的头顶,你可以建立一个空格分隔的列表的东西,如:

<li> 
    <xsl:attribute name="class"> 
     <xsl:if cond="...">correct</xsl:if> 
     <xsl:if cond="...">submitted</xsl:if> 
    </xsl:attribute> 
</li> 
+0

这不起作用(至少不使用PHP)。除了'if'元素外,没有任何空白,也不影响输出(你需要使用'text'元素)。当然,我可以使用这种解决方案,只需在每个可能的类名称后添加一个空格,但这会导致冗余空间,并且看起来比应该需要的更加混乱。 – Jakob 2009-10-26 16:33:07

+1

我已经成功地使用了它,所以也许XSLT处理器与XSLT文件本身的空白处理方式有所不同。 – 2009-10-27 10:33:45

+2

不应'cond'是'test'? – Maarten 2013-11-19 20:59:48

1

至于我知道,空格分隔的属性值不是XML数据模型的一部分,因此不能直接通过XSLT创建。

除非您正在转换为XML语言(不是HTML,XHTML是),否则您不应该担心XSLT 输出的XML有效性。这可以是任何东西,并且不需要符合XML!

+0

我不是说空白分隔的属性值是无效的XML,只是没有(据我所知)专门生成它们的XSLT构造。 – Jakob 2009-10-26 16:27:23

相关问题