复制后代节点并将其放在当前节点之后

时间:2017-03-29 09:29:10

标签: xslt xslt-2.0

在下面的xml中。我想做以下

  • 匹配wrapper/item,其子项或后代为<olr>
  • 如果找到,请复制<olr>及其所有后续兄弟,并粘贴它 在当前节点之后,即wrapper/item的结束。 (换言之,<olr> and its following-siblings将永远是<wrapper>)的直接子女
  • 休息应该按原样复制。

输入XML:

<root>
<wrapper>
    <item>
        <item>1.1</item>            
        <item>
            <olr>outlier1</olr>
        </item>
    </item>
    <item>
        <item>2.1</item>            
        <item>
            <item>
                <item>
                    <item>preceedingsibling1</item>
                    <item>preceedingsibling2</item>
                    <olr>outlier2</olr>
                    <item>followingsibling1</item>
                    <item>followingsibling2</item>
                </item>                   
            </item>
        </item>
    </item>
    <item>
        <item>3.1</item>            
        <item>
            <item>                   
                <item>3.3.1</item>                    
            </item>
        </item>
    </item>
</wrapper>

<root>
<wrapper>
    <item>
        <item>1.1</item>            
        <item>                
        </item>
    </item>
    <olr>outlier1</olr>
    <item>
        <item>2.1</item>            
        <item>
            <item>
                <item>
                    <item>preceedingsibling1</item>
                    <item>preceedingsibling2</item>                       
                </item>                   
            </item>
        </item>
    </item>
    <olr>outlier2</olr>
    <item>followingsibling1</item>
    <item>followingsibling2</item>
    <item>
        <item>3.1</item>            
        <item>
            <item>                   
                <item>3.3.1</item>                    
            </item>
        </item>
    </item>
</wrapper>

我正在尝试一些事情:

<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="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>  

<xsl:template match="item[descendant::olr]">
    <xsl:apply-templates select="node() except descendant::olr"/>
    <!-- ? not sure what to do here        -->
</xsl:template>    

2 个答案:

答案 0 :(得分:1)

实现这一目标的一种方法是使用

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">


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

    <xsl:template match="wrapper/item[descendant::olr]">
        <xsl:next-match/>
        <xsl:copy-of select="descendant::olr/(., following-sibling::node())"/>
    </xsl:template>

    <xsl:template match="wrapper/item//olr | wrapper/item//node()[preceding-sibling::olr]"/>
</xsl:transform>

http://xsltransform.net/bFWR5Fg。如果您有多个olr元素,我不确定会发生什么。

答案 1 :(得分:1)

以下 XSLT-2.0 解决方案可以执行此操作:

wrapper/item

有两个身份转换模板(第一个和第二个)以递归方式按原样复制元素。

第三个模板将descendant::olrolr匹配,并通过将其复制为自己的后续兄弟来专门处理olr(及其后续兄弟姐妹)。

第四个模板是在正常过程中对irb不执行任何操作。