Reputation:
I have the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<thesaurus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<term id="01">
<name>
<value>green</value>
</name>
<info>
<ref rid="12" obj-type="Building" />
</info>
<info>
<ref rid="13" obj-type="House" />
</info>
<info>
<ref rid="14" obj-type="Apartment"/>
</info>
</term>
<term id="02">
<name>
<value>blue</value>
</name>
<info>
<ref rid="24" obj-type="Unknown"/>
</info>
<info>
<ref rid="26" obj-type="Unknown"/>
</info>
<info>
<ref rid="29" obj-type="Unknown"/>
</info>
</term>
<term id="03">
<name>
<value>yellow</value>
</name>
</term>
<term id="04">
<name>
<value>red</value>
</name>
<info>
<ref rid="40" obj-type="Hotel"/>
</info>
<info>
<ref rid="41" obj-type="Building"/>
</info>
<info>
<ref rid="43" obj-type="House"/>
</info>
</term>
<term id="05">
<name>
<value>purple</value>
</name>
</term>
<term id="06">
<name>
<value>magenta</value>
</name>
<info>
<ref rid="60" obj-type="Building"/>
</info>
<info>
<ref rid="62" obj-type="Unknown"/>
</info>
<info>
<ref rid="64" obj-type="House"/>
</info>
</term>
</thesaurus>
What I want is this:
1) Select all
<term>
tags that without an<info>
tag. This is already accomplished with the first apply-templates: select="term[not(info)]" in the XSLT below.2) Select all
<term>
tags when its<ref>
tag contains anobj-type="Unknown"
alone or multiple times, but don't select it if it's surrounded byobj-types
with values different than "Unknown" (like Building or House).*** Inside an
<info>
tag, when havingobj-type
siblings with other values, it takes at least one value of 'Unknown' for the<term>
tag to not be selected.
If the XSLT works well, the tags selected will be:
02, 03, 05
where:
01 won't be selected because it contains
<info>
tags, and none of those tags has a obj-type='Unknown'02 will be selected because there are three multiple values of 'Unknown', and no other values different than 'Unknown'
03 will be selected because it does not contains
<info>
tags04 won't be selected because it contains
<info>
tags withobj-type
values different than 'Unknown'.05 will be selected because there are no info tags.
06 won't be selected because although there is one value of 'Unknown', all the other
<ref>
siblings have a valueobj-type
different than 'Unknown'.*** REMEMBER: Inside an
<info>
tag, when havingobj-type
siblings with other values, it takes at least one value of 'Unknown' for the<term>
tag to not be selected.
I'm using the XSLT below. With the first apply-templates I can select all the tags without an <info>
tag.
With the second apply-templates I can select all the <term>
tags that contain a <ref>
tag with an obj-type="Unknown"
, but I don't know how to tell the XSLT that if there are obj-types with a different value, don't select the corresponding <term>
tag.
I tried to use a for-each and a conditional, to iterate through all the <ref>
children and check whether one of the siblings had a different value than 'Unknown' to not select its <term>
parent, but to no avail.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text"/>
<xsl:template match="/thesaurus">
<xsl:apply-templates select="term[not(info)]"/>
<xsl:apply-templates select="term[info/ref[@obj-type='Unknown']]"/>
</xsl:template>
<xsl:template match="term">
<xsl:value-of select="@id"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="name"/>
<xsl:text>,</xsl:text>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="term[info/ref]">
<xsl:value-of select="@id"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="name"/>
<xsl:text>,</xsl:text>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
I hope it's clear.
Upvotes: 0
Views: 670
Reputation: 501
You could try selecting the terms who doesn't contain something other than Unknown
<xsl:apply-templates select="term[not(info/ref[@obj-type!='Unknown'])]"/>
Or adding an if statement in your term[info/ref]
template
<xsl:template match="term[info/ref]">
<xsl:if test="not(info/ref[@obj-type!='Unknown'])">
<xsl:value-of select="@id"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="name"/>
<xsl:text>,</xsl:text>
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
Upvotes: 0