Xslt 复制子节点并将其放置在当前节点之后

Xslt 复制子节点并将其放置在当前节点之后,xslt,xslt-2.0,Xslt,Xslt 2.0,在下面的xml中。我想做以下事情 匹配包装器/项,其子项或子项是 如果找到,请复制及其所有后续同级,然后粘贴它 在当前节点之后,即包装器/项目的末尾。(换句话说,及其后续同级将始终是的直接子级) 其余部分应按原样复制 输入XML: <root> <wrapper> <item> <item>1.1</item> <item> <

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

  • 匹配
    包装器/项
    ,其子项或子项是
  • 如果找到,请复制
    及其所有后续同级,然后粘贴它 在当前节点之后,即
    包装器/项目的末尾。(换句话说,
    及其后续同级将始终是
    的直接子级)
  • 其余部分应按原样复制
输入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>

1.1
异常值1
2.1
先例1
先例2
异常值2
以下兄弟姐妹1
以下兄弟姐妹2
3.1
3.3.1                    


1.1
异常值1
2.1
先例1
先例2
异常值2
以下兄弟姐妹1
以下兄弟姐妹2
3.1
3.3.1                    

我正在尝试一些东西:

<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>    


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

<?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>


。如果您有几个
olr
元素,我不确定会发生什么情况。

实现这一点的一种方法是使用

<?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>


。我不确定如果您有几个
olr
元素会发生什么情况。

下面的XSLT-2.0解决方案可以做到这一点:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    version="2.0">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <!-- identity transform template with mode='olr' -->
    <xsl:template match="@* | node()" mode="olr">
        <xsl:copy>
            <xsl:apply-templates select="@*, node()[1]" mode="olr"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]" mode="olr"/>
    </xsl:template>

    <!-- identity transform template -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*, node()[1]"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>

    <!-- copy the olr and it's following-elements in the current element -->
    <xsl:template match="wrapper/item[descendant::olr]">
        <xsl:copy>
            <xsl:apply-templates select="@*, node()[1]" />
        </xsl:copy>
        <xsl:apply-templates select="descendant::olr[not(preceding-sibling::olr)]" mode="olr"/>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>

    <!-- "do nothing for olr" template -->
    <xsl:template match="olr[ancestor::item/parent::wrapper]"/>

</xsl:stylesheet>

有两个标识转换模板(第一个和第二个)可以按原样递归复制元素

第三个模板将
包装器/项
后代::olr
匹配,并通过将其复制为自己的后续同级来专门处理
olr
(及其后续同级)


第四个模板是在正常过程中不为olr做任何事情。

下面的XSLT-2.0解决方案可以做到这一点:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    version="2.0">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <!-- identity transform template with mode='olr' -->
    <xsl:template match="@* | node()" mode="olr">
        <xsl:copy>
            <xsl:apply-templates select="@*, node()[1]" mode="olr"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]" mode="olr"/>
    </xsl:template>

    <!-- identity transform template -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*, node()[1]"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>

    <!-- copy the olr and it's following-elements in the current element -->
    <xsl:template match="wrapper/item[descendant::olr]">
        <xsl:copy>
            <xsl:apply-templates select="@*, node()[1]" />
        </xsl:copy>
        <xsl:apply-templates select="descendant::olr[not(preceding-sibling::olr)]" mode="olr"/>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>

    <!-- "do nothing for olr" template -->
    <xsl:template match="olr[ancestor::item/parent::wrapper]"/>

</xsl:stylesheet>

有两个标识转换模板(第一个和第二个)可以按原样递归复制元素

第三个模板将
包装器/项
后代::olr
匹配,并通过将其复制为自己的后续同级来专门处理
olr
(及其后续同级)


第四个模板是在正常过程中对
olr
不做任何事情。

您的解释是
前面的兄弟姐妹
,而预期的输出有
后面的兄弟姐妹
s和
olr
@LingamurthyCS-我的错。现在更正它。谢谢您的解释是
前面的兄弟姐妹
,而预期的输出有
后面的兄弟姐妹
s和
olr
@LingamurthyCS-我的坏。现在更正它。谢谢