Re: [xsl] I only want to process the first node... ;)

Subject: Re: [xsl] I only want to process the first node... ;)
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 18 Sep 2007 12:56:18 -0400
At 2007-09-18 18:13 +0200, Norman Rosner wrote:
I have an XML File that looks like this:
...

So there's an Analysis node and several S nodes as siblings. But
there are also CS and DL nodes as siblings of the Analysis node. What
i want is: Capitalize the first character of every @trans that occurs
first in a S node and just print the rest @trans as strings to sdtout ;)

That sounds to me like a current context list oriented problem and not a selection problem.

So thats what i wrote:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/ Transform"
                xmlns:xlink="http://www.w3.org/1999/xlink";
                xmlns:mt="machine_translation"
                xmlns:xml="http://www.w3.org/XML/1998/namespace";>

  <xsl:output method="text" omit-xml-declaration="yes"
standalone="yes" indent="no"/>

It is sufficient to say method="text" and not use any of the other attributes.

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


<!-- Capitalize the first character of a given word --> <xsl:function name="mt:capitalize_first"> <xsl:param name="word"/> <xsl:variable name="converted_first_char" select="translate (substring($word,1,1),'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>

Since you are using XSLT 2.0 you don't need to be this elaborate.


    <xsl:value-of
select="concat($converted_first_char,
substring ($word, 2, string-length($word)))"/>
  </xsl:function>

<xsl:template match="S">

See below for an example.


  But then i recognized that some S nodes can occur in a CS or DL
nodes, so i changed my XPath expression
(descendant::*[count (child::*) = 0]) to tis
one: ((ancestor::*)[2])/descendant::*[count
(child::*) = 0] just to test if it works when i take the ancestor
node that comes directly after the Analysis node. It works fine but
the fact is that i get the strings printed 2 or three times.

Which won't happen when you treat this as a context list issue.


So i know why it is printed or processed three times: There a three S
nodes inside the DL node. And here's the point: If i processed the
first S node inside a DL or CS node i don't want to process the
following S nodes in that CS or DL node.

Which gets problematic in different document contexts ... so avoid document context and just deal with the nodes you want as the context node list. You can pull all of the @trans descendants and just act differently on the first one.

I hope that somebody of you can help me and that somebody of you
understand the problem :)

I hope I understood! And that the below helps.


. . . . . . . . . . Ken


T:\ftemp>type norman.xml <?xml version="1.0" encoding="iso-8859-1"?> <Analysis>

.....
<S>
      <PPER id="s33_5" word="er" lemma="er" morph="3.Nom.Sg.Masc"
trans="he"/>
      <VVFIN id="s33_4" word="verlange" lemma="verlangen"
morph="3.Sg.Pres.Subj"
             trans="request"/>
      <NP>
         <PP>
                   <APPR id="s33_6" word="vor" lemma="vor" morph="--"
trans="over"/>
                   <PIS id="s33_7" word="allem" lemma="alle"
morph="Dat.Sg.Masc" trans="all"/>
         </PP>
         <CNP>
                   <NN id="s33_8" word="Arbeitsmoral" lemma="Arbeitsmoral"
morph="Acc.Sg.Fem"
                trans="employee moral"/>
                   <KON id="s33_9" word="und" lemma="und" morph="--"
trans="and"/>
                   <NP>
                      <ADJA id="s33_10" word="ordentliches"
lemma="ordentlich" morph="Pos.Acc.Sg.Neut"
                     trans="proper"/>
                      <NN id="s33_11" word="Auftreten" lemma="auftreten"
morph="Acc.Sg.Neut"
                   trans="appearence"/>
                   </NP>
         </CNP>
      </NP>
      <PP>
         <APPR id="s33_1" word="Von" lemma="von" morph="--"
trans="of | from"/>
         <PPOSAT id="s33_2" word="seinen" lemma="sein"
morph="Dat.Pl.*" trans="her"/>
         <NN id="s33_3" word="Beschftigten" lemma="beschftigter"
morph="Dat.Pl.*"
             trans="employees"/>
      </PP>
  </S>
  <DL>
      <CS>
         <S>
                   <NE id="s34_1" word="Perot" lemma="Perot"
morph="Nom.Sg.Masc" trans="Perot"/>
                   <VAFIN id="s34_2" word="sei" lemma="sein"
morph="3.Sg.Pres.Subj" trans="would be"/>
                   <NP>
                      <ART id="s34_3" word="ein" lemma="ein"
morph="Nom.Sg.Masc" trans="an"/>
                      <ADJA id="s34_4" word="autoritrer"
lemma="autoritr" morph="Pos.Nom.Sg.Masc"
                     trans="authoritarian"/>
                      <NN id="s34_5" word="Macher" lemma="Macher"
morph="Nom.Sg.Masc" trans="wright"/>
                   </NP>
         </S>
         <KON id="s34_7" word="und" lemma="und" morph="--"
trans="and"/>
         <S>
                   <NP>
                      <PPOSAT id="s34_11" word="seine" lemma="sein"
morph="Nom.Sg.Fem" trans="her"/>
                      <NN id="s34_12" word="Schwche" lemma="Schwche"
morph="Nom.Sg.Fem"
                   trans="weakness"/>
                   </NP>
                   <VAFIN id="s34_9" word="sei" lemma="sein"
morph="3.Sg.Pres.Subj" trans="would be"/>
                   <ADV id="s34_10" word="auch" lemma="auch" morph="--"
trans="too"/>
         </S>
      </CS>
      <S>
         <NP>
                   <ART id="s34_16" word="ein" lemma="ein"
morph="Nom.Sg.Masc" trans="a"/>
                   <NN id="s34_17" word="Manager" lemma="Manager"
morph="Nom.Sg.Masc" trans="manager"/>
         </NP>
         <VVFIN id="s34_14" word="beschreibt" lemma="beschreiben"
morph="3.Sg.Pres.Ind"
                trans="describes"/>
         <PPER id="s34_15" word="ihn" lemma="ihn"
morph="3.Acc.Sg.Masc" trans="him"/>
      </S>
  </DL>
</Analysis>

T:\ftemp>type norman.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="2.0">

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

<xsl:template match="S">
  <!--grab all descendant attributes-->
  <xsl:for-each select=".//@trans">
    <xsl:choose>
      <!--which one is this one?-->
      <xsl:when test="position()=1">
        <!--this is the first of the @trans attributes below S-->
        <xsl:value-of select="upper-case(substring(.,1,1))"/>
        <xsl:value-of select="substring(.,2)"/>
      </xsl:when>
      <xsl:otherwise>
        <!--all others go out without capitalization-->
        <xsl:text> </xsl:text>
        <xsl:value-of select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
  <xsl:text>
</xsl:text>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>call xslt2 norman.xml norman.xsl norman.txt


..... He request over all employee moral and proper appearence of | from her employees Perot would be an authoritarian wright Her weakness would be too A manager describes him



--
Upcoming public training: UBL and code lists Oct 1/5; Madrid Spain
World-wide corporate, govt. & user group XML, XSL and UBL training
RSS feeds:     publicly-available developer resources and training
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Cancer Awareness Jul'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

Current Thread