遇到特定节点时将节点内容一分为二 [英] split node contents in two when encoutering a specific node

查看:27
本文介绍了遇到特定节点时将节点内容一分为二的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,这是我拥有的 XML 文档:

Ok so here's the XML document I have:

输入

<parent>
  <para> text 1 <NodeTypeA>element1</NodeTypeA> text2 <Xref ref="1"/> text3</para>
</parent>

我想将外部参照节点放在 para 节点之外,但我希望它将 para 一分为二,如下所示:

I would like to take the Xref node outside of the para node, but I would like it to split the para in two, like this:

想要的输出

<parent>
  <para> text 1 <NodeTypeA>element1</NodeTypeA> text2 </para>
  <Xref ref="1"/>
  <para> text3</para>
</parent>

对于段落中的其余内容,我希望它保持相同的结构,我只想要外部参照并将其拆分.但我真的不知道我是如何做到这一点的.

For the rest of the contents inside the para, I would like it to keep the same structure, I just want the Xref out and splitting it. But I really can't see how I can achieve that.

推荐答案

在 XSLT 2/3 中,这只是 xsl:for-each-group group-adjacent 的另一个用例,在这种情况下使用 xsl:for-each-group select="node()" group-adjacent="boolean(self::Xref)":

In XSLT 2/3 this is just another use case for xsl:for-each-group group-adjacent, in this case with xsl:for-each-group select="node()" group-adjacent="boolean(self::Xref)":

  <xsl:template match="para">
      <xsl:for-each-group select="node()" group-adjacent="boolean(self::Xref)">
          <xsl:choose>
              <xsl:when test="current-grouping-key()">
                  <xsl:copy-of select="current-group()"/>
              </xsl:when>
              <xsl:otherwise>
                  <para>
                      <xsl:copy-of select="current-group()"/>
                  </para>
               </xsl:otherwise>
           </xsl:choose>
        </xsl:for-each-group>
    </xsl:template>

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

在带有兄弟递归的 XSLT 1 中,您可以按照

In XSLT 1 with sibling recursion you can work along the lines of

<xsl:template match="para[Xref]">
    <xsl:apply-templates select="node()[1]"/>
</xsl:template>

<xsl:template match="para/node()[not(self::Xref)]">
    <xsl:param name="group" select="."/>
    <xsl:apply-templates select="following-sibling::node()[1]">
        <xsl:with-param name="group" select="$group | ."/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="para/node()[not(self::Xref) and not(following-sibling::Xref)][last()]">
    <xsl:param name="group" select="."/>
    <para>
        <xsl:copy-of select="$group | ."/>
    </para>
</xsl:template>

<xsl:template match="para/Xref">
    <xsl:param name="group"/>
    <xsl:if test="$group">
        <para>
            <xsl:copy-of select="$group"/>
        </para>
    </xsl:if>
    <xsl:copy-of select="."/>
    <xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>

https://xsltfiddle.liberty-development.net/jz1PuP7/2

但它在边缘情况下很容易损坏,所以我没有对其进行彻底测试以判断任何外部参照和其他节点的序列是否给出了正确的结果.上面有输入的特定部分(即 para[Xref])及其转换的模板,添加身份转换来处理其余部分.

But it can break easily in edge cases so I haven't tested it thoroughly to tell whether any sequence of Xref and other nodes gives the right result. And the above has the templates for that particular part of the input (i.e. para[Xref]) and its transformation, add the identity transformation to handle the rest.

这篇关于遇到特定节点时将节点内容一分为二的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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