首页 > 解决方案 > xsl 将以下同级移动到当前标记

问题描述

我需要移动当前元素内的当前元素之后的以下兄弟姐妹。我不明白为什么我正在做的事情不起作用,你能帮我理解为什么吗?

我有这个 XML 输入:

<book>
<prelim>
    <introd></introd>
    <introd></introd>
    <bibl></bibl>
    <bibl></bibl>
</prelim>

我需要有这个输出:

<book>
<prelim>
    <introd></introd>
    <introd>
        <bibl></bibl>
        <bibl></bibl>
    </introd>
</prelim>

它尝试了这个:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="*"><xsl:element name="{local-name()}"><xsl:apply-templates/></xsl:element>
</xsl:template>
<xsl:template match="introd">
    <introd>
    <xsl:apply-templates/>
    <xsl:variable name="i"><xsl:value-of select="following-sibling::bibl/position()"/></xsl:variable>
    <xsl:if test="following-sibling::*[$i]=following-sibling::bibl[$i]">
            <xsl:apply-templates select="following-sibling::bibl[following-sibling::*[$i]=following-sibling::bibl[$1]]"></xsl:apply-templates>
    </xsl:if>
    </introd>
</xsl:template>
</xsl:stylesheet>

谢谢!玛丽亚

标签: xmlxslt

解决方案


我建议匹配prelim然后使用xsl:for-each-group select="*" group-starting-with="introd"

  <xsl:template match="prelim">
      <xsl:copy>
          <xsl:for-each-group select="*" group-starting-with="introd">
              <xsl:copy>
                  <xsl:apply-templates select="node(), tail(current-group())"/>
              </xsl:copy>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

其余的可以通过身份转换处理,可以xsl:mode在 XSLT 3 ( https://xsltfiddle.liberty-development.net/naZYrpT ) 中声明或在 XSLT 2 中拼写为模板。在 XSLT 2tail中不可用,但您可以使用subsequence(current-group(), 2)反而。


推荐阅读