2010-02-18 74 views
4

如何以特定顺序编写元素属性而无需明确写入?按特定顺序排列属性以便输出

考虑:

<xsl:template match="Element/@1|@2|@3|@4"> 
    <xsl:if test="string(.)"> 
     <span> 
      <xsl:value-of select="."/><br/> 
     </span> 
    </xsl:if> 
</xsl:template> 

的属性应该出现的顺序1, 2, 3, 4。不幸的是,你不能保证在XML属性的顺序,也可能是<Element 2="2" 4="4" 3="3" 1="1">

所以上面的模板将产生如下:

<span>2</span> 
<span>4</span> 
<span>3</span> 
<span>1</span> 

理想的情况下,我不想要测试,如果它的每个属性已经有了价值。我想知道如果我能以某种方式设置我的显示顺序?或者我需要明确地做,并重复如果测试如下:

<xsl:template match="Element"> 

    <xsl:if test="string(./@1)> 
     <span> 
      <xsl:value-of select="./@1"/><br/> 
     </span> 
    </xsl:if> 
    ... 
    <xsl:if test="string(./@4)> 
     <span> 
      <xsl:value-of select="./@4"/><br/> 
     </span> 
    </xsl:if> 
</xsl:template> 

在这种情况下可以做什么?

+0

谢谢各位的回复。 我不是很清楚。我并不需要通过名称对属性进行排序,而是自己指定一个订单。 说一个文档将需要按顺序1,2,3,4显示它们。另一个按顺序2,3。另一个可以说是3,1,2,4。 我想知道是否可以存储以某种方式确定属性名称的特定顺序......然后通过它们迭代。 基本上,为了显示一系列属性值,有一些简洁和非常灵活的方法。 希望有道理? – DashaLuna 2010-02-18 16:55:01

回答

6

在之前的问题中,您似乎使用了XSLT 2.0,所以我希望这次也可以使用XSLT 2.0解决方案。

订单不是在模板的匹配模式中确定的,而是在您执行xsl:apply-templates时确定的。所以(使用XSLT 2.0),你可以简单地按你想要的顺序编写一系列属性,例如<xsl:apply-templates select="@att2, @att1, @att3"/>将按照该顺序处理属性。

XSLT 1.0没有序列,只有节点集。要产生相同的结果,请按要求顺序使用xsl:apply-templates,例如:

<xsl:apply-templates select="@att2"/> 
<xsl:apply-templates select="@att1"/> 
<xsl:apply-templates select="@att3"/> 
1

我会使用属性的本地名称上的xsl:sort来获得您想要的结果。我也会使用不同的模式,所以结果不会在别的地方偶然被调用。

<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="Element"> 
     <xsl:apply-templates select="@*" mode="sorted"> 
     <xsl:sort select="local-name()" /> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="Element/@a|@b|@c|@d" mode="sorted"> 
    <xsl:if test="string(.)"> 
     <span> 
      <xsl:value-of select="."/><br/> 
     </span> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 
3

请勿生成依赖于属性顺序的XML。这是非常脆弱的,至少可以说我会认为这是一种糟糕的风格。 XML不是那样设计的; <elem a="1" b="2" /><elem a="1" b="2" />明确等同。

如果您想要订购输出,请订购您的输出(而不是依赖有序输入)。

此外,match="Element/@1|@2|@3|@4"不等于match="Element/@1|Element/@2|Element/@3|Element/@4",但我相信你是指后者。

话虽这么说,你可以这样做:

<xsl:template match="Element/@1|Element/@2|Element/@3|Element/@4"> 
    <xsl:if test="string(.)"> 
    <span> 
     <xsl:value-of select="."/><br/> 
    </span> 
    </xsl:if> 
</xsl:template> 

<xsl:template match="Element"> 
    <xsl:apply-templates select="@1|@2|@3|@4"> 
    <!-- order your output... --> 
    <xsl:sort select="name()" /> 
    </xsl:apply-templates> 
</xsl:template> 

编辑:我会把它作为读取@1等只是例子,因为名称实际上不能用XML数字开头。