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

Re: Unable to select wanted nodes

Subject: Re: Unable to select wanted nodes
From: "Mark" <mark@xxxxxxxxxxxx>
Date: Thu, 6 Oct 2011 16:00:46 -0700
Re:  Unable to select wanted nodes
Hi Brandon,
You are quite right of course, these routines will be embedded in a more complex environment. It will take some time to test that out to see if I was able to capture all of the requirements in that small sample. Thanks for the suggestions on simplifying the code that already worked. I'll let you know.


Regards,
Mark

-----Original Message----- From: Brandon Ibach
Sent: Thursday, October 06, 2011 3:41 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: Unable to select wanted nodes


Hi, Mark...

The following produces the output you indicated, though it may need to
be tweaked a bit if your actual requirements are more complicated than
your sample would indicate.  Note that the for-each-group uses a
composite key of the attribute and its value to essentially
de-duplicate the list of formats.

<xsl:for-each-group select="../../Stamp/Formats"
group-by="concat(name(@*), '=', @*)">
 <xsl:variable name="active" select="name(@*) = $format and @* = $number"/>
 <xsl:element name="Formats">
   <xsl:if test="position() gt 1">
     <xsl:attribute name="label" select="position() - 1"/>
   </xsl:if>
   <xsl:attribute name="state" select="if ($active) then 'depressed'
else 'active'"/>
   <xsl:copy-of select="@*"/>
 </xsl:element>
</xsl:for-each-group>

Also, the code for the content of the following "StampButtons" element
could be simplified, first avoiding duplication by moving the "more
than one" check deeper in and second by removing the for-each-group.
Since you're not doing anything with the groups other than a for-each
on their members, you don't really need the grouping and you can do
the filtering right up front, which will also fix the behavior of the
"more than one" check, which would have produced incorrect results,
had your test data included an "only-one" case.  The following should
replace the xsl:choose.

<xsl:variable name="stamps"
select="../../Stamp[Formats/@*[name(.)=$format][.=$number]]"/>
<xsl:for-each select="$stamps">
 <xsl:element name="Stamp">
   <xsl:if test="count($stamps) gt 1">
     <xsl:attribute name="label" select="position()"/>
   </xsl:if>
   <xsl:attribute name="state" select="'active'"/>
   <xsl:copy-of select="CatNumbers/@pofis-number"/>
 </xsl:element>
</xsl:for-each>

For some final tweaks, you can actually incorporate the xsl:if at the
top of the (match="Formats" mode="formats") template into the match
expression as a predicate so the template won't even be used if that
condition isn't true (the built-in template for an element with only
attributes and no content will produce nothing).

Also, it is somewhat a matter of personal style, but your
comprehensive use of xsl:element and xsl:attribute makes for code that
is both more verbose and less obvious in intent, from a casual glance.
I think the more "template-like" style of using literal result
elements and attribute value templates (name="{...}"), where possible,
makes for more readable code.  Just the opinion of an old C++ (here
and there) hack, tho... ;)

-Brandon :)


On Thu, Oct 6, 2011 at 4:02 PM, Mark <mark@xxxxxxxxxxxx> wrote:
For the below <Input> file, I want the <DesiredOutput> file but so far I
have only been able to write code that produces <MyOutput>.

In <MyOutPut>:
(1) The mode="stamp" templates produce satisfactory <StampPage> elements.
These templates and their output were included only for completeness and may
be ignored.


(2) The mode="formats" templates produce the <FormatPage> and its child
<StampButtons> properly, but I cannot puzzle out how to produce the children
of <FormatButtons>. I am not even sure that what I have done so far is the
best way to do this.


Side note: the redundant attribute in the <FormatPage> element appears
solely as debugging aid.

Help graciously accepted,
Mark

<Input>
  <Set>
    <Stamp>
      <CatNumbers pofis-number="105"/>
      <Formats souvenir-sheet="105"/>
      <Formats se-tenant="105"/>
    </Stamp>
    <Stamp>
      <CatNumbers pofis-number="106"/>
      <Formats souvenir-sheet="105"/>
      <Formats se-tenant="105"/>
    </Stamp>
    <Stamp>
      <CatNumbers pofis-number="107"/>
      <Formats souvenir-sheet="105"/>
      <Formats se-tenant="107"/>
    </Stamp>
    <Stamp>
      <CatNumbers pofis-number="108"/>
      <Formats souvenir-sheet="105"/>
      <Formats se-tenant="107"/>
    </Stamp>
  </Set>
 </Input>
----------------
<DesiredOutput>
  <StampPage>
    <FormatButtons>
      <Formats state="active" souvenir-sheet="105"/>
      <Formats state="active" se-tenant="105"/>
    </FormatButtons>
    <StampButtons>
      <Stamp state="depressed" pofis-number="105"/>
    </StampButtons>
  </StampPage>
  <StampPage>
    <FormatButtons>
      <Formats state="active" souvenir-sheet="105"/>
      <Formats state="active" se-tenant="105"/>
    </FormatButtons>
    <StampButtons>
      <Stamp state="depressed" pofis-number="106"/>
    </StampButtons>
  </StampPage>
  <StampPage >
    <FormatButtons>
      <Formats state="active" souvenir-sheet="105"/>
      <Formats state="active" se-tenant="107"/>
    </FormatButtons>
    <StampButtons>
      <Stamp state="depressed" pofis-number="107"/>
    </StampButtons>
  </StampPage>
  <StampPage>
    <FormatButtons>
      <Formats state="active" souvenir-sheet="105"/>
      <Formats state="active" se-tenant="107"/>
    </FormatButtons>
    <StampButtons>
      <Stamp state="depressed" pofis-number="108"/>
    </StampButtons>
  </StampPage>
  <FormatPage souvenir-sheet="105">
    <FormatButtons>
      <Formats state="depressed" souvenir-sheet="105"/>
      <Formats label="1" state="active" se-tenant="105"/>
      <Formats label="2" state="active" se-tenant="107"/>
    </FormatButtons>
    <StampButtons>
      <Stamp label="1" state="active" pofis-number="105"/>
      <Stamp label="2" state="active" pofis-number="106"/>
      <Stamp label="3" state="active" pofis-number="107"/>
      <Stamp label="4" state="active" pofis-number="108"/>
    </StampButtons>
  </FormatPage>
  <FormatPage se-tenant="105">
    <FormatButtons>
      <Formats state="active" souvenir-sheet="105"/>
      <Formats label="1" state="depressed" se-tenant="105"/>
      <Formats label="2" state="active" se-tenant="107"/>
    </FormatButtons>
    <StampButtons>
      <Stamp label="1" state="active" pofis-number="105"/>
      <Stamp label="2" state="active" pofis-number="106"/>
    </StampButtons>
  </FormatPage>
  <FormatPage se-tenant="107">
    <FormatButtons>
      <Formats state="active" souvenir-sheet="105"/>
      <Formats label="1" state="active" se-tenant="105"/>
      <Formats label="2" state="depressed" se-tenant="107"/>
    </FormatButtons>
    <StampButtons>
      <Stamp label="1" state="active" pofis-number="107"/>
      <Stamp label="2" state="active" pofis-number="108"/>
    </StampButtons>
  </FormatPage>
 </DesiredOutput>

-------------------
<MyOutput>
 <StampPage>
  <FormatButtons>
    <Formats state="active" souvenir-sheet="105"/>
    <Formats state="active" se-tenant="105"/>
  </FormatButtons>
  <StampButtons>
    <Stamp state="depressed" pofis-number="105"/>
  </StampButtons>
 </StampPage>
 <StampPage>
  <FormatButtons>
    <Formats state="active" souvenir-sheet="105"/>
    <Formats state="active" se-tenant="105"/>
  </FormatButtons>
  <StampButtons>
    <Stamp state="depressed" pofis-number="106"/>
  </StampButtons>
 </StampPage>
 <StampPage>
  <FormatButtons>
    <Formats state="active" souvenir-sheet="105"/>
    <Formats state="active" se-tenant="107"/>
  </FormatButtons>
  <StampButtons>
    <Stamp state="depressed" pofis-number="107"/>
  </StampButtons>
 </StampPage>
 <StampPage>
  <FormatButtons>
    <Formats state="active" souvenir-sheet="105"/>
    <Formats state="active" se-tenant="107"/>
  </FormatButtons>
  <StampButtons>
    <Stamp state="depressed" pofis-number="108"/>
  </StampButtons>
 </StampPage>
 <FormatPage souvenir-sheet="105">
  <FormatButtons>
    <!-- My problem -->
  </FormatButtons>
  <StampButtons>
    <Stamp label="1" state="active" pofis-number="105"/>
    <Stamp label="2" state="active" pofis-number="106"/>
    <Stamp label="3" state="active" pofis-number="107"/>
    <Stamp label="4" state="active" pofis-number="108"/>
  </StampButtons>
 </FormatPage>
 <FormatPage se-tenant="105">
  <FormatButtons>
    <!-- My problem -->
  </FormatButtons>
  <StampButtons>
    <Stamp label="1" state="active" pofis-number="105"/>
    <Stamp label="2" state="active" pofis-number="106"/>
  </StampButtons>
 </FormatPage>
 <FormatPage se-tenant="107">
  <FormatButtons>
    <!-- My problem -->
  </FormatButtons>
  <StampButtons>
    <Stamp label="1" state="active" pofis-number="107"/>
    <Stamp label="2" state="active" pofis-number="108"/>
  </StampButtons>
 </FormatPage>
</MyOutput>

------------------------
Stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs
xd"
 version="2.0">

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

 <xsl:template match="Set">
  <xsl:element name="Output">
    <xsl:apply-templates mode="stamp"/>
    <xsl:apply-templates mode="formats"/>
  </xsl:element>
 </xsl:template>

 <!-- Create a StampPage for every Stamp -->
 <xsl:template match="Stamp" mode="stamp">
  <xsl:element name="StampPage">
    <xsl:element name="FormatButtons">
      <xsl:apply-templates mode="stamp"/>
    </xsl:element>
    <xsl:element name="StampButtons">
      <xsl:element name="Stamp">
        <xsl:attribute name="state" select="'depressed'"/>
        <xsl:attribute name="pofis-number"
select="CatNumbers/@pofis-number"/>
      </xsl:element>
    </xsl:element>
  </xsl:element>
 </xsl:template>

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

 <xsl:template match="Formats" mode="stamp">
  <xsl:element name="Formats">
    <xsl:attribute name="state" select="'active'"/>
    <xsl:copy-of select="@*"/>
  </xsl:element>
 </xsl:template>

<xsl:template match="Formats" mode="formats">
<xsl:if test="@* eq ../CatNumbers/@pofis-number">
<xsl:element name="FormatPage">
<xsl:copy-of select="@*"/>
<xsl:variable name="format" select="name(@*)"/>
<xsl:variable name="number" select="@*"/>
<xsl:element name="FormatButtons">
<!-- I do not know how to select the correct components -->
</xsl:element>
<xsl:element name="StampButtons">
<xsl:choose>
<xsl:when test="count(../../Stamp/Formats/@*[name(.)=$format]) eq
1">
<xsl:element name="Stamp">
<xsl:attribute name="state" select="'active'"/>
<xsl:copy-of select="../CatNumbers/@pofis-number"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:for-each-group select="../../Stamp/Formats"
group-by="@*[name(.)=$format]">
<xsl:for-each select="current-group()">
<xsl:if test="@* eq $number">
<xsl:element name="Stamp">
<xsl:attribute name="label" select="position()"/>
<xsl:attribute name="state" select="'active'"/>
<xsl:copy-of select="../CatNumbers/@pofis-number"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:for-each-group>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:template>


</xsl:stylesheet>

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.