XSLT for filtering XML based on attribute value?

E

elora_c

I'm trying to write XSLT that will filter out an XML based on an
attribute's value. XML looks like:

<postings>
<channel name="A">
<posting Connected="True" name="Posting1" />
<posting Connected="False" name="Posting2" />
</channel>
<channel name="B">
<channel name="C">
<posting Connected="True" name="Posting3" />
</channel>
</channel>
</postings>

Output should look like:
<postings>
<posting Connected="True" name="Posting1" />
<posting Connected="True" name="Posting3" />
</postings>

So, I'm trying to extract all nodes that have the attribute value
Connected="True." Any node that doesn't have the Connected attribute,
or whose value isn't True should be ignored. I can filter out those
nodes whose value isn't True, but that still leaves the Channel nodes
that don't have the attribute. And when I try to explicitly filter out
the Channel nodes, nothing gets processed since the posting nodes are
children of Channel nodes. If it helps, Channel nodes will never have
the Connected attribute and Posting nodes always will.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2004/10/xpath-functions"
xmlns:xdt="http://www.w3.org/2004/10/xpath-datatypes">

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

<xsl:template match="//*[@Connected='False']">
</xsl:template>
</xsl:stylesheet>

Can anyone help?
Thanks,
Carole
 
N

nstonge

Try adding

<xsl:template match="channel">
<xsl:apply-templates select="node()"/>
</xsl:template>

to your XSL. This will process the children of the channel elements
without coping them.

Normand
 
V

Volkm@r

So, I'm trying to extract all nodes that have the attribute value
Connected="True." Any node that doesn't have the Connected attribute, [...]
<xsl:template match="//*[@Connected='False']">
</xsl:template>
</xsl:stylesheet>

Can anyone help?
Thanks,
Carole

So, what if you tried:

<xsl:template match="//*[not(@Connected='True')]">
</xsl:template>
 
E

elora_c

The problem with that is that it will ignore the channel nodes and not
process their children. Using the suggestion from the previous post
did it:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2004/10/xpath-functions"
xmlns:xdt="http://www.w3.org/2004/10/xpath-datatypes">

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

<xsl:template match="channel">
<xsl:apply-templates select="node()"/>
</xsl:template>

<xsl:template match="//*[@Connected='False']">
</xsl:template>

</xsl:stylesheet>
 

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,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top