订单中的XSL Process属性

时间:2012-04-21 03:17:16

标签: xslt

我需要按特定顺序处理属性(具有它们的任何节点)。例如:

<test>
    <event 
        era  ="modern"
        year ="1996"
        quarter = "first"
        day = "13"
        month= "January"
        bcad ="ad"
        hour ="18"
        minute = "23"
        >The big game began.</event>
    <happening 
        era  ="modern"
        day = "18"
        bcad ="ad"
        month= "February"
        hour ="19"
        minute = "24"
        >The big game ended.</happening>
    <other>Before time existed.</other>
</test>

这个

<xsl:template match="test//*">
    <div>
        <xsl:apply-templates select="@*" />
        <xsl:apply-templates />
    </div>
</xsl:template>

<xsl:template match="@*">
    <span class="{name()}">
        <xsl:value-of select="."/>
    </span>
</xsl:template>

会根据我的需要格式化。也就是说,我会得到

<div><span class="era">modern</span>
     <span class="year">1996</span>
     <span class="quarter">first</span>
     <span class="day">13</span>
     <span class="month">January</span>
     <span class="bcad">ad</span>
     <span class="hour">18</span>
     <span class="minute">23</span>The big game began.</div>
<div><span class="era">modern</span>
     <span class="day">18</span>
     <span class="bcad">ad</span>
     <span class="month">February</span>
     <span class="hour">19</span>
     <span class="minute">24</span>The big game ended.</div>
<div>Before time existed.</div>

(虽然没有我在这里添加的新内容以便易读)。

但属性的顺序不一定是正确的。

要解决此问题,我可以将<xsl:apply-templates select="@*" />更改为<xsl:call-template name="atts" />并添加以所需顺序应用模板的模板,如下所示:

<xsl:template match="test//*">
    <div>
        <xsl:call-template name="atts" />
        <xsl:apply-templates />
    </div>
</xsl:template>

<xsl:template name="atts">
    <xsl:apply-templates select="@era" />
    <xsl:apply-templates select="@bcad" />
    <xsl:apply-templates select="@year" />
    <xsl:apply-templates select="@quarter" />
    <xsl:apply-templates select="@month" />
    <xsl:apply-templates select="@day" />
    <xsl:apply-templates select="@hour" />
    <xsl:apply-templates select="@minute" />        
</xsl:template>

<xsl:template match="@*">
    <span class="{name()}">
        <xsl:value-of select="."/>
    </span>
</xsl:template>

这是以指定顺序处理属性的最佳实践方法吗?我一直想知道是否有使用密钥或全局变量的方法。

我需要使用XSLT 1.0,在实际情况中,有几十个属性,而不仅仅是八个。

1 个答案:

答案 0 :(得分:1)

与元素相比,例如,XML中的属性顺序并不重要,即XPath和XSLT可以按任何顺序处理它们。因此,强制给定订单的唯一方法是以某种方式指定它。一种方法是在上一个代码示例中明确地调用它们。您还可以提取所有属性名称并将它们存储在单独的XML文件中,例如,

之类的东西
<attributes>
  <attribute>era</attribute>
  <attribute>year</attribute>
  <attribute>month</attribute>
  ...
<attributes>

现在您可以使用document()函数加载这些元素并迭代所有属性元素:

<xsl:variable name="attributes" select="document('attributes.xml')//attribute"/>
...
<xsl:template match="*">
  <xsl:variable name="self" select="."/>
  <xsl:for-each select="$attributes">
    <xsl:apply-templates select="$self/@*[name()=current()]"/>
  </xsl:for-each>    
</xsl:template>