xsl-list
[Top] [All Lists]

Re: Matching a first instance.

2003-11-29 01:51:02
This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:myIDs="my:Ids"
 exclude-result-prefixes="myIDs">

 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*" />

 <myIDs:myIDs>
   <id>personal</id>
   <id>handheld</id>
 </myIDs:myIDs>

 <xsl:variable name="vIDs" select="document('')/*/myIDs:*/*"/>

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

  <xsl:template match="TestElement[(_at_)xmlid='testID']/*">
    <xsl:choose>
    <xsl:when test="@xmlid = $vIDs
                and
                  not(preceding-sibling::*[(_at_)xmlid = $vIDs])">
      <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:attribute name="cost">0</xsl:attribute>
      </xsl:copy>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="ident"/>
    </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

when applied on your source.xml:

<t>
  <TestElement xmlid="testID">
    <adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In
The
Set We Care About" />
    <adder xmlid="handheld" cost="2" alias="handheld computers" />
    <adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In
The
Set We Care About" />
    <adder xmlid="personal" cost="2" alias="personal computers" />
  </TestElement>
  <TestElement xmlid="testID">
    <adder xmlid="personal" cost="2" alias="personal computers" />
    <adder xmlid="handheld" cost="2" alias="handheld computers" />
    <adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In
The
Set We Care About" />
  </TestElement>
</t>

produces the wanted result:

<t>
   <TestElement xmlid="testID">
      <adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In
The  Set We Care About"/>
      <adder xmlid="handheld" cost="0" alias="handheld computers"/>
      <adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In
The  Set We Care About"/>
      <adder xmlid="personal" cost="2" alias="personal computers"/>
   </TestElement>
   <TestElement xmlid="testID">
      <adder xmlid="personal" cost="0" alias="personal computers"/>
      <adder xmlid="handheld" cost="2" alias="handheld computers"/>
      <adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In
The  Set We Care About"/>
   </TestElement>
</t>

Please, also note that according to the XML spec names starting with "xml"
are reserved and are not recommended to be used.



=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

"Ben Trafford" <ben(_at_)prodigal(_dot_)ca> wrote in message
news:5(_dot_)2(_dot_)0(_dot_)9(_dot_)2(_dot_)20031128205856(_dot_)037d3168(_at_)pop3(_dot_)sympatico(_dot_)ca(_dot_)(_dot_)(_dot_)

Hi!

I have a somewhat unusual problem. I want to match an xsl:if test to the
first occurrence of an element with an attribute of a particular value. An
example snippet of XML to be transformed:

<TestElement xmlid="testID">
<adder xmlid="personal" cost="2" alias="personal computers" />
<adder xmlid="handheld" cost="2" alias="handheld computers" />
<adder xmlid="network" cost="2" alias="networked computers" />
<adder xmlid="mainframe" cost="2" alias="mainframe" />
</TestElement>

The test needs to find all the TestElements whose xmlid is
'testID''.  Then find the first child element whose xmlid matches any of
those listed. Then change that child element's "cost" attribute to "0".
Leave the other "cost" attributes alone.

So, the above snippet would be changed to:

<TestElement xmlid="testID">
<adder xmlid="personal" cost="0" alias="personal computers" />
<adder xmlid="handheld" cost="2" alias="handheld computers" />
<adder xmlid="network" cost="2" alias="networked computers" />
<adder xmlid="mainframe" cost="2" alias="mainframe" />
</TestElement>

The following snippet:

<TestElement xmlid="testID">
<adder xmlid="Not_In_The_Set_To_Be_Recognized"
<adder xmlid="handheld" cost="2" alias="handheld computers" />
</TestElement>

  would be changed to:

<TestElement xmlid="testID">
<adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In The
Set We Care About" />
<adder xmlid="handheld" cost="0" alias="handheld computers" />
</TestElement>

And the following:

<TestElement xmlid="testID">
<adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In The
Set We Care About" />
<adder xmlid="handheld" cost="2" alias="handheld computers" />
<adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In The
Set We Care About" />
<adder xmlid="personal" cost="2" alias="personal computers" />
</TestElement>
<TestElement xmlid="testID">
<adder xmlid="personal" cost="2" alias="personal computers" />
<adder xmlid="handheld" cost="2" alias="handheld computers" />
<adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In The
Set We Care About" />
</TestElement>

would become:

<TestElement xmlid="testID">
<adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In The
Set We Care About" />
<adder xmlid="handheld" cost="0" alias="handheld computers" />
<adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In The
Set We Care About" />
<adder xmlid="personal" cost="2" alias="personal computers" />
</TestElement>
<TestElement xmlid="testID">
<adder xmlid="personal" cost="0" alias="personal computers" />
<adder xmlid="handheld" cost="2" alias="handheld computers" />
<adder xmlid="Not_In_The_Set_To_Be_Recognized" cost="1" alias="Not In The
Set We Care About" />
</TestElement>

Any help would be much appreciated. Note that the "xmlid" attributes being
used are -not- unique. They will re-occur.

--->Ben


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list






 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



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