Remove parent element with a child element matching a given rule

P

patrizio.trinchini

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
 
J

Joseph Kesselman

<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']"/>
 
J

Joseph Kesselman

Martin said:
<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.
 
P

patrizio.trinchini

Joseph, Martin

thanks a lot for your precious help, your suggested solutions works
perfectly!
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,991
Messages
2,570,217
Members
46,805
Latest member
ClydeHeld1

Latest Threads

Top