【问题标题】:XSLT switching order of elementsXSLT 元素的切换顺序
【发布时间】:2016-04-06 11:43:25
【问题描述】:

我需要切换元素,例如就像在这个 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

【问题讨论】:

  • 规则是什么?查找xsl:sort ...
  • 我需要 site1/site2 在 site3/site4 的定义之后。必须是输出 xml 中的最后一个。我有很多这个网站的定义,我用它们的名字来识别它们。
  • 请尝试使用 XSLT 更新您的问题。这是一个以(如果没有的话)开头的参考:XSLT Custom Sort

标签: xml xslt sitecore


【解决方案1】:

如果无法通过xsl:sort 所需的成对排序关系来指定site 元素的所需顺序,那么您可能正在寻求重新排列一组预先确定的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 提出的这个好建议。

【讨论】:

  • 我还要提一下,XSLT 2.0 允许它更紧凑,只需编写 &lt;xsl:apply-templates select="site[@name='site3'], site[@name='site4'], site[@name='site1'], site[@name='site2']"/&gt;
  • 是的,这是一个很好的建议。答案已更新。谢谢!
  • 我需要详细说明我到底想做什么。我有site1-site10,然后是site11-site100,这10个站点需要在site100之后。但实际上我不知道有多少站点定义只有我知道我需要删除这 10 个站点。
  • 如果这个答案没有帮助,是的,我同意你必须更好地明确你想要做什么。
  • 请让我知道我的解释是否正确或需要更多说明我的意图。
【解决方案2】:

OP 问题,更准确

在游戏后期,in comments 看起来 OP 需要的不是按 name 过滤来重新排列四个项目中的两个,而是显然要提取第一个 10 项并在所有其他项之后输出它们(编写样式表时不知道确切的数量)。

解法原理

只应用模板两次,使用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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 2012-07-01
    相关资源
    最近更新 更多