Remove parent element with a child element matching a given rule

Discussion in 'XML' started by patrizio.trinchini@googlemail.com, Aug 17, 2006.

  1. Guest

    Hi all,

    I'm new to XSLT and maybe my problem have a very trivial answer, but I
    need an expert that point me in the right direction.
    What I would obtain is to remove all the elements that have a child
    element with an attribute set at a given value; maybe an example is
    more self-explaining...

    Given the following input XML document:

    <?xml version="1.0" encoding="UTF-8"?>
    <sample xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNameSpaceSchemaLocation="sample.xsd">
    <parent-element>
    <child-element name="a child element"/>
    <test-element type="removeme">This should be removed</test-element>
    </parent-element>
    <parent-element>
    <child-element name="a child element"/>
    <test-element type="keepme">This should be keept</test-element>
    </parent-element>
    </sample>

    I would obtain the following output XML document:

    <?xml version="1.0" encoding="UTF-8"?>
    <sample xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNameSpaceSchemaLocation="sample.xsd">
    <parent-element>
    <child-element name="a child element"/>
    <test-element type="keepme">This should be keept</test-element>
    </parent-element>
    </sample>

    where the first occurrence of the element 'parent-element' has been
    removed because one of its child elements (namely the <test-element>
    element) has the attribute 'type' whose value is 'removeme'.

    I've defined the following XSLT:

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:eek:utput indent="yes"/>
    <xsl:template match="@*|node()">
    <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
    </xsl:template>
    <xsl:template match="test-element[@type='removeme']"/>
    </xsl:stylesheet>

    but all I'm able to obtain is the following document:

    <?xml version="1.0" encoding="UTF-16"?>
    <sample xsi:noNameSpaceSchemaLocation="sample.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <parent-element>
    <child-element name="a child element"></child-element>
    </parent-element>
    <parent-element>
    <child-element name="a child element"></child-element>
    <test-element type="keepme">This should be keept</test-element>
    </parent-element>
    </sample>

    where only the <test-element> element that matches the aforementioned
    rule hase been removed, not its ancestor

    Any suggestion?

    Thanks a lot for your help

    Patrizio
    , Aug 17, 2006
    #1
    1. Advertising

  2. wrote:


    > <xsl:template match="test-element[@type='removeme']"/>


    That should be
    <xsl:template match="parent-element[test-element[@type='removeme']]"/>

    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Aug 17, 2006
    #2
    1. Advertising

  3. wrote:
    > <xsl:template match="test-element[@type='removeme']"/>


    That matches and discards a <test-element> which has the specified
    attribute (and all its descendants, of course).

    If you want to match the parent of that test-element, say so: Any
    element which has a test-element child which has the specified type:

    > <xsl:template match="*[test-element/@type='removeme']"/>


    --
    Joe Kesselman / Beware the fury of a patient man. -- John Dryden
    Joseph Kesselman, Aug 17, 2006
    #3
  4. Martin Honnen wrote:
    > <xsl:template match="parent-element[test-element[@type='removeme']]"/>


    More specific than my use of *, and thus better in most cases unless
    test-element will appear in a wide variety of parent elements.

    --
    Joe Kesselman / Beware the fury of a patient man. -- John Dryden
    Joseph Kesselman, Aug 17, 2006
    #4
  5. Guest

    Joseph, Martin

    thanks a lot for your precious help, your suggested solutions works
    perfectly!
    , Aug 22, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page