删除同名

时间:2015-04-23 05:55:12

标签: xslt

我正在尝试使用XSLT转换以下xml:

 <level>
    <nextlevel>
        <note> text text text </note>
    </nextlevel>
    <nextlevel> 
        <abc>
        </abc>
        <note>bla bla bla </note>
        <note>bla bla bla bla bla</note>
        <xyz>
        </xyz>
    </nextlevel>
    <nextlevel>
        <note> text text text </note>
    </nextlevel>
</level>

我想删除重复节点“note”,只有当它连续出现两次时才会删除。输出应如下所示:

<level>
 <nextlevel>
    <note> text text text </note>
 </nextlevel>
  <nextlevel>   
    <abc>
    </abc>
    <xyz>
    </xyz>
 </nextlevel>
 <nextlevel>
    <note> text text text </note>
 </nextlevel>
</level>

我正在使用以下xslt:

<xsl:key name="dup" match="note" use="concat(generate-id(..), '|', name())"/>

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

<xsl:template match="note[not(generate-id() = generate-id(key('dup', concat(generate-id(..), '|', .))[1]))]"/>

但是,所有名为“note”的节点都被删除了,我的xslt出了什么问题?

3 个答案:

答案 0 :(得分:0)

尝试使用此功能可避免重复具有相同值的同名连续节点

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

      <xsl:template match="*[not(*)][name() = preceding-sibling::*[1]/name()][@value = preceding-sibling::*[1]/@value]" />

答案 1 :(得分:0)

在这里使用XSLT 1.0是一个建议:

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

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

<xsl:template match="note[(preceding-sibling::*[1][not(self::note)] or not(preceding-sibling::*[1]))
                          and following-sibling::*[1][self::note]
                          and (following-sibling::*[2][not(self::note)] or not(following-sibling::*[2]))]"/>

<xsl:template match="note[preceding-sibling::*[1][self::note]
                          and (preceding-sibling::*[2][not(self::note)] or not(preceding-sibling::*[2]))
                          and (following-sibling::*[1][not(self::note)] or not(following-sibling::*[1]))]"/>

</xsl:stylesheet>

应用于输入

 <level>
    <nextlevel>
        <note> text text text </note>
    </nextlevel>
    <nextlevel> 
        <abc>
        </abc>
        <note>bla bla bla </note>
        <note>bla bla bla bla bla</note>
        <xyz>
        </xyz>
    </nextlevel>
    <nextlevel>
        <note> text text text </note>
    </nextlevel>
    <nextlevel>
        <foo>bar</foo>
        <note>...</note>
        <note>...</note>
        <note>...</note>
        <note>...</note>
        <bar>baz</bar>
    </nextlevel>
</level>

输出

<level>
    <nextlevel>
        <note> text text text </note>
    </nextlevel>
    <nextlevel>
        <abc>
        </abc>


        <xyz>
        </xyz>
    </nextlevel>
    <nextlevel>
        <note> text text text </note>
    </nextlevel>
    <nextlevel>
        <foo>bar</foo>
        <note>...</note>
        <note>...</note>
        <note>...</note>
        <note>...</note>
        <bar>baz</bar>
    </nextlevel>
</level>

答案 2 :(得分:0)

  

我想删除重复节点“note”仅在它出现两次时才会删除   连续。

也许这可能只是:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="note[count(../note) > 1]"/>

</xsl:stylesheet>

这将删除任何另外note作为兄弟姐妹的note。如果备注连续很重要,您可以将删除模板更改为:

<xsl:template match="note[preceding-sibling::node()[1][self::note] or following-sibling::node()[1][self::note]]"/>