根据父节点删除子节点

时间:2017-04-12 07:08:44

标签: xslt

以下示例Xml有2个不同的集合,一个是" 模式"还有一个是" 会员"。 模式成员的子集。

<Root>
    <Pattern name="A">
        <Member id="2" />
        <Member id="4"/>
        <Member id="10"/>
        <Member id="11"/>
    </Pattern>
    <Pattern name="B">
        <Member id="3" />
        <Member id="4"/>
        <Member id="10"/>
        <Member id="11"/>
        <Member id="12"/>
        <Member id="13"/>
    </Pattern>
    <Members>
        <Member id="1" name="Member1">
            <Member id="2" name="Member2">
                <Member id="3" name="Member3"/>
                <Member id="4" name="Member4"/>
            </Member>
            <Member id="5" name="Member5">
                <Member id="6" name="Member6"/>
                <Member id="7" name="Member7"/>
            </Member>
            <Member id="8" name="Member8">
                <Member id="9" name="Member9"/>
            </Member>
            <Member id="10" name="Member10">
                <Member id="11" name="Member11"/>
            </Member>
            <Member id="12" name="Member12">
                <Member id="13" name="Member13"/>
                <Member id="14" name="Member14">
                    <Member id="15" name="Member15"/>
                    <Member id="16" name="Member16">
                        <Member id="17" name="Member17">
                            <Member id="18" name="Member18"/>
                            <Member id="19" name="Member19"/>
                            <Member id="20" name="Member20"/>
                        </Member>
                    </Member>
                </Member>
            </Member>
        </Member>
    </Members>
</Root>

我需要从模式中删除子节点条目,当父项及其子项存在时,将其属性id与成员的属性ID进行比较。

以上的预期输出是

<Output>
<Pattern name="A">
        <Member id="2" />       
        <Member id="10"/>
    </Pattern>
    <Pattern name="B">
        <Member id="3" />
        <Member id="4"/>
        <Member id="10"/>
        <Member id="12"/>
    </Pattern>
</Output>

模式A: 在4名成员中,成员4是成员2的孩子。因此,成员4必须被删除。会员11是会员10的孩子。所以会员11必须删除。

其他模式的逻辑相同。

帮助我实现xslt 1.0。

感谢

1 个答案:

答案 0 :(得分:0)

您可以定义一个键,按ID

查找Member元素
<xsl:key name="members" match="Members//Member" use="@id" />

然后,对于给定的Pattern/Member元素,您可以像这样获取父ID

<xsl:variable name="parentId" select="key('members', @id)/parent::*/@id" />

然后,您可以测试是否需要将当前Member复制到输出

<xsl:if test="not(../Member/@id = $parentId)">
    <xsl:copy-of select="." />
</xsl:if>

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:key name="members" match="Members//Member" use="@id" />

    <xsl:template match="Pattern/Member">
      <xsl:variable name="parentId" select="key('members', @id)/parent::*/@id" />
      <xsl:if test="not(../Member/@id = $parentId)">
          <xsl:copy-of select="." />
      </xsl:if>
    </xsl:template>

    <xsl:template match="Members" />

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

实际上,您可以撤消逻辑,而是检查您不想复制的Member元素。

尝试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:key name="members" match="Members//Member" use="@id" />

    <xsl:template match="Pattern/Member[../Member/@id = key('members', @id)/parent::*/@id]" />

    <xsl:template match="Members" />

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