XSLT切换元素的顺序

时间:2016-04-06 11:43:25

标签: xml xslt sitecore

我需要切换元素,例如就像在这个xml中一样:

<configuration>
  <sites>
   <site name="site1"/>
   <site name="site2" />
   <site name="site3"/>
   <site name="site4"/>
  </sites>
</configuration>

为:

<configuration>
  <sites>
   <site name="site3"/>
   <site name="site4" />
   <site name="site1"/>
   <site name="site2"/>
  </sites>
</configuration>

通过XSLT。任何人都可以帮助进行这种转变吗?

<xsl:template match="node()|@*">
  <xsl:copy>
     <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>

<xsl:variable name="site1" select="configuration/sites/site[@name='site1']" />

<xsl:variable name="site2" select="configuration/sites/site[@name='site2']" />

<xsl:template match="site[@name='site1'"/>
<xsl:template match="site[@name='site2'"/>


<xsl:template match="configuration/sitecore/sites">
  <xsl:apply-templates select="node()|@*"/>
  <xsl:value-of select="$site1"/>
  <xsl:value-of select="$site2"/>
</xsl:template>

我尝试做的是,我不确定是否可以使用某个变量来存储所有特定元素内容,删除节点的相应元素副本,并将其附加到最后。

由于

Krp0

2 个答案:

答案 0 :(得分:2)

如果无法通过site所需的成对排序关系来指定所需的xsl:sort元素顺序,那么您可能需要重新排列预先设定的sites纯粹基于预定的排序,仅按其@name属性区分:

XSLT 1.0

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="sites">
    <xsl:copy>
      <xsl:apply-templates select="site[@name='site3']"/>
      <xsl:apply-templates select="site[@name='site4']"/>
      <xsl:apply-templates select="site[@name='site1']"/>
      <xsl:apply-templates select="site[@name='site2']"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

我已经通过身份转换证明了这一点,以获得最大的灵活性,但您可以通过xsl:copy-of而不是xsl:apply-templates等来回避一般性。

XSLT 2.0

在XSLT 2.0中,可以使用单个xsl:apply-templates

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="sites">
    <xsl:copy>
      <xsl:apply-templates select="site[@name='site3'],
                                   site[@name='site4'],
                                   site[@name='site1'],
                                   site[@name='site2']"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

信用:感谢@Martin Honnen提出这个好建议。

答案 1 :(得分:0)

OP问题,更精确

在游戏的后期,in comments看起来好像OP不需要按名称进行过滤以将四项中的两项重新排序,但显然要提取第一个 10 < / strong>项,然后将其输出到所有 other 项之后(在编写样式表时,其确切编号未知)。

解决方案原理

使用position()运算符仅两次应用模板:

  <xsl:template match="sites">
    <xsl:copy>
      <xsl:apply-templates select="site[position()>10]"/>
      <xsl:apply-templates select="site[10>=position()]"/>
    </xsl:copy>
  </xsl:template>

或(可读性较差,但不会混淆某些不完整的解析器和语法突出显示器):

      <xsl:apply-templates select="site[position()&gt;10]"/>
      <xsl:apply-templates select="site[10&gt;=position()]"/>

可重现溶液

此文件:

<configuration>
  <sites>
   <site name="site1"/>
   <site name="site2" />
   <site name="site3"/>
   <site name="site4"/>
   <site name="site5"/>
   <site name="site6"/>
   <site name="site7"/>
   <site name="site8"/>
   <site name="site9"/>
   <site name="site10"/>
   <site name="site11"/>
   <site name="site12"/>
   <site name="site13"/>
   <site name="site14"/>
   <site name="site15"/>
   <site name="site16"/>
   <site name="site17"/>
  </sites>
</configuration>

转换为此(缺少换行符):

<?xml version="1.0"?>
<configuration>
  <sites>
    <site name="site11"/>
    <site name="site12"/>
    <site name="site13"/>
    <site name="site14"/>
    <site name="site15"/>
    <site name="site16"/>
    <site name="site17"/>
    <site name="site1"/>
    <site name="site2"/>
    <site name="site3"/>
    <site name="site4"/>
    <site name="site5"/>
    <site name="site6"/>
    <site name="site7"/>
    <site name="site8"/>
    <site name="site9"/>
    <site name="site10"/>
  </sites>
</configuration>

通过

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@*|*|processing-instruction()|comment()|node()">
    <xsl:copy>
      <xsl:apply-templates select="*|@*|text()|processing-instruction()|comment()|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="sites">
    <xsl:copy>
      <xsl:apply-templates select="site[position()&gt;10]"/>
      <xsl:apply-templates select="site[10&gt;=position()]"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

经过

测试
xsltproc -o out.xml sheet.xsl in.xml && cat out.xml