[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: filtering problem

Subject: Re: filtering problem
From: Adrian Herscu <adrian.herscu@xxxxxxxxx>
Date: Sat, 19 Jun 2010 21:12:02 +0300
 Re: filtering problem
Hi Michael,

thanks for the help :)

I tried to apply your idea on my template (written in XSL 1.0 + Xalan Extensions); here is what I got:

The input xml:
<?xml version="1.0" encoding="UTF-8"?>
<procedure name="RunSomething">
  <command src="10" />
  <command src="11" />
  <command src="12" />
  <command src="13" />
  <call name="DoFoo">
    <command src="20" />
    <command src="21" />
    <command src="22" />
    <call name="MakeFoo">
      <command src="30" />
      <command src="31" failed="true()" />
      <command src="32" />
    </call>
    <command src="24" />
    <command src="25" failed="true()" />
    <call name="WriteFoo">
      <command src="40" />
      <command src="41" failed="true()" />
      <command src="42" />
    </call>
    <command src="26" />
  </call>
</procedure>

The XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan"
exclude-result-prefixes="xalan">


  <xsl:output method="xml" indent="yes" encoding="UTF-8"
    media-type="text/xml" xalan:indent-amount="2" />

<xsl:strip-space elements="*" />

<xsl:variable name="firstFailure" select="(//command[@failed=true()])[1]" />
<xsl:variable name="pathToFirstFailure"
select="xalan:nodeset($firstFailure)/ancestor-or-self::*" />


  <xsl:template match="command[@failed=true()]">
    <failing-command src="{@src}" />
  </xsl:template>

<xsl:template
match="*[xalan:intersection(node(), xalan:nodeset($pathToFirstFailure))]">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>


<xsl:template match="*" />

</xsl:stylesheet>

The output:
<?xml version="1.0" encoding="UTF-8"?>
<procedure name="RunSomething">
  <call name="DoFoo">
    <call name="MakeFoo">
      <failing-command src="31" />
    </call>
    <failing-command src="25" />
  </call>
</procedure>

My problem is with the <failing-command src="25" /> element; it should not be generated. How do I filter it out?

Thanks,
Adrian.

On 6/17/2010 12:15 PM, Michael Kay wrote:

Perhaps something like this:


<xsl:variable name="firstFailure"
select="(//command[@failed='true()])[1]"/>

<xsl:variable name="pathToFirstFailure"
select="$firstFailure/ancestor-or-self::*"/>

<xsl:template match="*[. intersect $pathToFirstFailure]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

<xsl:template match="*"/>

You don't see this coding pattern very often, but I sometimes find it
quite useful: select the "interesting" nodes in a global variable, and
then use this global variable in a match pattern to steer which template
rule is used to process which nodes. In XSLT 2.1 you will be able to
replace the match pattern above with

match="$pathToFirstFailure"

Michael Kay
Saxonica

On 17/06/2010 09:54, Adrian Herscu wrote:
Hi all,

Consider the following input XML file:

<?xml version="1.0" encoding="UTF-8"?>
<batch name="level1">
<command src="1" />
<command src="2" failed="true()" />
<command src="3" />
<command src="4" failed="true()" />
<batch name="level2">
<command src="10" />
<command src="11" failed="true()" />
<command src="12" />
<batch name="level3">
<command src="20" />
<command src="21" failed="true()" />
<command src="22" />
</batch>
<command src="30" />
<command src="31" failed="true()" />
<command src="32" />
</batch>
</batch>

I need an XSL transformation that scans the top-level batch until it
finds a command marked as failed, no matter at which internal
batch-level it is, preserving the batch level on the report.

Currently, I have this XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan">

<xsl:output method="xml" indent="yes" encoding="UTF-8"
media-type="text/xml" xalan:indent-amount="2" />

<xsl:strip-space elements="*" />

<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>

<!--
FIXME: batches are matched even though there is a prior failed
command or batch containing a failed command
-->
<xsl:template match="batch">
<batch name="{@name}">
<xsl:apply-templates />
</batch>
</xsl:template>

<!-- match only the first failing command -->
<xsl:template match="command[@failed=true()][1]">
<failed-command src="{@src}" />
</xsl:template>
</xsl:stylesheet>

which generates:

<?xml version="1.0" encoding="UTF-8"?>
<batch xmlns:xalan="http://xml.apache.org/xalan" name="level1">
<failed-command src="2" />
<batch name="level2">
<failed-command src="11" />
<batch name="level3">
<failed-command src="21" />
</batch>
</batch>
</batch>

instead of:

<?xml version="1.0" encoding="UTF-8"?>
<batch xmlns:xalan="http://xml.apache.org/xalan" name="level1">
<failed-command src="2" />
</batch>

Another example -- if only command[@src='21'] is marked failed, then
the generated output should be:

<?xml version="1.0" encoding="UTF-8"?>
<batch name="level1">
<batch name="level2">
<batch name="level3">
<failed-command src="21" />
</batch>
</batch>
</batch>

Thanks for your help,
Adrian.

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.