xsl-list
[Top] [All Lists]

Re: Re: How to do an 'existence' test in XSL? - Simple but Generalised

2004-12-23 06:59:35
The modified solution you wrote would cause problem,
if <gui type=""> nodes would exist in the ancestor
axis.. (because preceding axis does'nt include nodes
from the ancestor axis).

for e.g., if your XSL is applied to this XML -
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <othertag>
     <gui type="x"></gui>
   </othertag>
   <gui type="tooltip"></gui>
   <gui type="help"></gui>
   <gui type="tooltip"></gui>
   <othertag>
     <gui type="alertBox"> <!-- Please note here -->
       <gui type="alertBox"></gui>
     </gui> 
   </othertag>
   <gui type="tooltip"></gui>
   <gui type="help"></gui>
</root>

it will produce output -
<root>
   <x/>
   <tooltip/>
   <help/>
   <alertBox/>
   <alertBox/>
</root>

We need to write the XSL like this -
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  
<xsl:output method="xml" indent="yes" />
  
<xsl:template match="/root">
  <root>
    <xsl:for-each select="//gui">
      <xsl:if test="not((@type = preceding::gui/@type)
or (@type = ancestor::gui/@type))">
        <xsl:element name="{(_at_)type}" />
      </xsl:if>        
    </xsl:for-each>
  </root>
</xsl:template>
  
</xsl:stylesheet>

Regards,
Mukul

--- ben(_at_)autonomic(_dot_)net wrote:

I wondered if Mukul's suggestion could be
generalised to function on cases where the desired
tags in the input xsl may be at any level of nesting
e.g. with 'alertBox' we might have :

 <root>
   <othertag>
     <gui type="alertBox"></gui>
   </othertag>
   <gui type="tooltip"></gui>
   <gui type="help"></gui>
   <gui type="tooltip"></gui>
   <othertag>
     <deepertag>
       <gui type="alertBox"></gui>
     </deepertag> 
   </othertag>
   <gui type="tooltip"></gui>
   <gui type="help"></gui>
 </root> 

By changing the gui select in the for-each and the
if test from preceeding-sibling to preceeding it (I
think) simply scans backwards in the document to see
if it has already encountered the type or not. 

 <?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
   
 <xsl:output method="xml" indent="yes" />
   
 <xsl:template match="/root">
   <root>
     <xsl:for-each select="//gui">
       <xsl:if test="not(@type =
 preceding::gui/@type)">
         <xsl:element name="{(_at_)type}" />
       </xsl:if>
     </xsl:for-each>
   </root>
 </xsl:template>
   
 </xsl:stylesheet>

I have not tested it exhaustively, but it seems to
work perfectly, and does not depend on knowing what
types are available beforehand. 

+In what ways might this +not+ be the general
solution to the problem?+ 

It is certainly logical, and elegant.

I look forward to your responses with interest.

Dr T.B.Senior


You wrote:
Here is a simple approach you can try..

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  
<xsl:output method="xml" indent="yes" />
  
<xsl:template match="/root">
  <root>
    <xsl:for-each select="gui">
      <xsl:if test="not(@type =
preceding-sibling::gui/@type)">
        <xsl:element name="{(_at_)type}" />
      </xsl:if>
    </xsl:for-each>
  </root>
</xsl:template>
  
</xsl:stylesheet>

When the above XSL is applied to XML -
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <gui type="alertBox"></gui>
  <gui type="tooltip"></gui>
  <gui type="help"></gui>
  <gui type="tooltip"></gui>
  <gui type="alertBox"></gui>
  <gui type="tooltip"></gui>
  <gui type="help"></gui>
</root>  

The o/p recieved is -
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <alertBox/>
  <tooltip/>
  <help/>
</root>

Regards,
Mukul

--- ben(_at_)autonomic(_dot_)net wrote:

I'm having great difficulty understanding how/if
XSL
provides the tool to satisfy the following
simple
requirement. 

Lets say I have some simple xml like :

<gui type="alertBox">...</gui>
<gui type="tooltip">...</gui>
<gui type="help">...</gui>
<gui type="tooltip">...</gui>
<gui type="alertBox">...</gui>
<gui type="tooltip">...</gui>
<gui type="help">...</gui>

To simplify things... imagine transforming this
document in such a way that we have something
like :

<alertBox/>
<tooltip/>
<help/>

i.e. I would like the XSL to result in one
output
per gui type.

So there is the problem... how on earth do I
process
the xml such that it results in an output per
+type+
rather than for each instance (is that explained
well enough?)... i.e. it's easy to match on the
attributes but each match produces output so I
would
get :

<alertBox/><alertBox/>
<tooltip/><tooltip/><tooltip/>
<help/><help/>

Can anyone offer advice on the way in which I
ought
to approach this problem?

Kindest regards,

Ben



                
__________________________________ 
Do you Yahoo!? 
Yahoo! Mail - Helps protect you from nasty viruses. 
http://promotions.yahoo.com/new_mail

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>