XSLT 通过 splitter-element 拆分元素 [英] XSLT split elements by splitter-element

查看:18
本文介绍了XSLT 通过 splitter-element 拆分元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已尝试将此处提出的类似问题的解决方案结合起来,但所有这些解决方案都适用于非常具体的情况.我的情况如下:我有一个包含一些标签的任意 xml 文档,比如说 .我想要的是像这样拆分这些标签的父元素:

I've tried to combine solutions to the similar questions asked here but all of them work in very specific cases. My case is the following: I have an arbitrary xml document which contains some tags, let's say <separator/>. What I want is to split parent elements of these tags like that:

输入:

<some_tag some_attr="some_value">
    some text
    <some_other_tag>some another text</some_other_tag>
    <separator/>
    some other content
</some_tag>

输出:

<some_tag some_attr="some_value">
    some text
    <some_other_tag>some another text</some_other_tag>
</some_tag>
<separator/>
<some_tag some_attr="some_value">
    some other content
</some_tag>

另外,我仅限于 XSLT 1.0,因为项目中使用了 Xalan

Also, I am limited to XSLT 1.0 since Xalan is used in the project

推荐答案

要么使用兄弟递归,要么使用键来查找属于"分隔符的节点.复制最后一个分隔符之后的内容需要额外小心:

Either use sibling recursion or use a key to find the nodes "belonging" to a separator. Additional care is needed to copy stuff following the last separator:

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

  <xsl:output method="xml" indent="yes"/>

  <xsl:key name="sep" match="*[separator]/node()[not(self::separator)]" use="generate-id(following-sibling::separator[1])"/>

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

  <xsl:template match="*[separator]">
      <xsl:apply-templates select="separator" mode="split"/>
      <xsl:if test="separator[last()]/following-sibling::node()">
          <xsl:copy>
              <xsl:apply-templates select="@* | separator[last()]/following-sibling::node()"/>
          </xsl:copy>
      </xsl:if>
  </xsl:template>

  <xsl:template match="separator" mode="split">
      <xsl:apply-templates select=".." mode="split">
          <xsl:with-param name="separator" select="."/>
      </xsl:apply-templates>
      <xsl:copy-of select="."/>
  </xsl:template>

  <xsl:template match="*" mode="split">
      <xsl:param name="separator"/>
      <xsl:copy>
          <xsl:apply-templates select="@* | key('sep', generate-id($separator))"/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/pPqsHTc

请注意,如果您使用 Xalan Java,那么在 Java 世界中,使用 Saxon 9 和 XSLT 2/3 的 <xsl:for-each-group select="node()" group-adjacent= 会容易得多"boolean(self::separator)">group-starting-with="separator".

Note that if you use Xalan Java then in the Java world this is much easier with Saxon 9 and XSLT 2/3's <xsl:for-each-group select="node()" group-adjacent="boolean(self::separator)"> or group-starting-with="separator".

这篇关于XSLT 通过 splitter-element 拆分元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆