Remove sibling elements according to the value of an attribute

P

patrizio.trinchini

Hi,

how can remove sibling elements based on the value of an attribute ?

For instance, gven the XML document:

<root>
<parentElment>
<testElement name="A">
<removableElement/>
</parentElment>
<parentElment>
<testElement name="B">
<removableElement/>
</parentElment>
</root>

I would write a XSLT transformer that implements the following rule:

IF testElement[@name='A'] THEN <remove sibling element
removableElement>

so that the resultng XML document looks lke the following:

<root>
<parentElment>
<testElement name="A">
</parentElment>
<parentElment>
<testElement name="B">
<removableElement/>
</parentElment>
</root>

Thanks a lot for any suggestion
 
J

Joseph Kesselman

IF testElement[@name='A'] THEN <remove sibling element
removableElement>

Reverse the logic: when processing removableElements, copy them only if
there is not a testElement[@name='A']
 
P

Peter Flynn

Hi,

how can remove sibling elements based on the value of an attribute ?

For instance, gven the XML document:

<root>
<parentElment>
<testElement name="A">
<removableElement/>
</parentElment>
<parentElment>
<testElement name="B">
<removableElement/>
</parentElment>
</root>

I would write a XSLT transformer that implements the following rule:

IF testElement[@name='A'] THEN <remove sibling element
removableElement>

so that the resultng XML document looks lke the following:

<root>
<parentElment>
<testElement name="A">
</parentElment>
<parentElment>
<testElement name="B">
<removableElement/>
</parentElment>
</root>

Think of it the other way round: if the attribute value is not A,
then process the following sibling:

<xsl:template match="testElement">
<testElement>
<xsl:if test="@name!='A' and following-sibling::removableElement">
<removableElement/>
</xsl:if>
</testElement>
</xsl:template>

///Peter
 
P

patrizio.trinchini

Thanks a lot for your suggestions; applying them I was able to obtain
what I wanted, but I'm wandering if there is a better approach to get
the same result...

Given the source 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="AAA" value="XXX"/>
<sibling-element-1 id="001">Sibling 1</sibling-element-1>
<sibling-element-2 id="002">Sibling 2</sibling-element-2>
</parent-element>
<parent-element>
<child-element name="BBB" value="XXX"/>
<sibling-element-1 id="010">Sibling 1>/sibling-element-1>
<sibling-element-2 id="020">Sibling 2</sibling-element-2>
</parent-element>
<parent-element>
<child-element name="CCC" value="XXX"/>
<sibling-element-1 id="100">Sibling 1</sibling-element-1>
<sibling-element-2 id="200">Sibling 2</sibling-element-2>
</parent-element>
</sample>

I can obtain the following desired result:

<?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="AAA" value="aNewValue1"></child-element>
<sibling-element-1 id="001">Sibling 1</sibling-element-1>
<sibling-element-2 id="002">Sibling 2</sibling-element-2>
</parent-element>
<parent-element>
<child-element name="BBB" value="aNewValue2"></child-element>
<sibling-element-1 id="010">Sibling 1</sibling-element-1>
<sibling-element-2 id="020">Sibling 2</sibling-element-2>
</parent-element>
<parent-element>
<child-element name="CCC" value="aNewValue3"></child-element>
</parent-element>
</sample>

using the following XSLT transformer:

<?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="child-element[@name = 'AAA']/@value">
<xsl:attribute name="{name()}">aNewValue1</xsl:attribute>
</xsl:template>
<xsl:template match="child-element[@name = 'BBB']/@value">
<xsl:attribute name="{name()}">aNewValue2</xsl:attribute>
</xsl:template>
<xsl:template match="child-element[@name = 'CCC']/@value">
<xsl:attribute name="{name()}">aNewValue3</xsl:attribute>
</xsl:template>
<xsl:template match="parent-element/sibling-element-1">
<xsl:if test="preceding-sibling::child-element[@name != 'CCC']">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="parent-element/sibling-element-2">
<xsl:if test="preceding-sibling::child-element[@name != 'CCC']">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

Do you think that this is a valid approach or maybe there is a better
one, especially for the removal of elements according to the value of
the name attribute of the sibling child-element ?

Thanks again for your support.

Regards,

Patrizio
 

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

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top