Avatar of jmc430
jmc430

asked on 

Remove Trailing Periods in a Defined List of Abbreviations -- PLEASE HELP!

Greetings!

Is it possible to remove all trailing periods in an element tag, <HEAD>, but KEEP the trailing periods whenever it matches a word within a defined list of abbreviations?  

There exists a relatively short list (~50) of abbreviated words that must KEEP the trailing period.

For example:
Mr.
Mrs.
Ms.
C.A.
U.S.

I already have the functionality to remove all trailing periods (thanks Geert!):

    <xsl:template name="removeTrailingDot">
        <xsl:param name="argument"/>
        <xsl:param name="normArg" select="normalize-space($argument)"/>
        <xsl:choose>
            <xsl:when test="substring($normArg, string-length($normArg), 1) = '.'">
                <xsl:value-of select="substring($normArg, 1, string-length($normArg) - 1)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$normArg"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

However, I would like to disable this "removeTrailingDot" functionality whenever the string is defined as within the list of abbreviations.   Is this possible using the "contains" keyword (iterate through the list and check to see if the substring matches an abbreviation)?  

I have tried without success, and the Map functionality does not work within the confines of my development environment.

Any advice or guidance is greatly appreciated!

Best regards,
Jamie



XML

Avatar of undefined
Last Comment
Gertone (Geert Bormans)
Avatar of htang_us
htang_us

         <xsl:when test="substring($normArg, string-length($normArg), 1) = '.'">
                <!-- Here we know the word is ending with period. So we can do test here -->
                <!-- You can put the special list of words in a file, import it, iterate the word list to see if
                  any one match the current $normArg. If test is true, simply jump out the test. Otherwise,
                  at the end of the loop, remove the trailing period. -->
                <!-- you should use ends-with() function instead contains() since you want to remove trailing period, not the period in the middle
                  of the sentence -->
                <xsl:value-of select="substring($normArg, 1, string-length($normArg) - 1)"/>
            </xsl:when>
 
hope this helps
Avatar of Gertone (Geert Bormans)
Hi jmc430,
> I have tried without success, and the Map functionality does not work
> within the confines of my development environment.

that would be the easiest way to tackle this
what is your environment?
maybe you can use nodesets, that has a similar effect
Cheers!
htang_us,
> You can put the special list of words in a file,

well, if you can't use map, it is likely because the document('') function is not allowed....
Avatar of jmc430
jmc430

ASKER

Hi htang_us,

Thanks for writing me back!

I have the list of words in a file, abbrev.txt.  Is this the way I access it?

"document('../abbrev.txt')"

How do I iterate the word list to see if they match the current $normArg?  Can you provide me with some additional details?

Thanks so much for helping me!

Avatar of jmc430
jmc430

ASKER

Hi Geert!

Thanks for writing me back! :)

How can I use nodesets?

Thanks again for helping me!!


Avatar of jmc430
jmc430

ASKER

Hi...

I tried testing the values within my abbrev.xml file, to no avail:

      <xsl:when test="substring($normArg, string-length($normArg), 1) = '.'">
               
                  <xsl:if test="$normArg = document('../abbrev.xml')//abbreviations/abbrev">   * I am trying to compare here *
                   <xsl:value-of select="$normArg"/>
            </xsl:if>
                <xsl:value-of select="substring($normArg, 1, string-length($normArg) - 1)"/>
            </xsl:when>

How do I iterate through the values within the XML file containing the list of abbreviations?  

Please help me!

Any advice or guidance is greatly appreciated.

Best regards,
Jamie
Avatar of jmc430
jmc430

ASKER

(the "document" function is indeed allowed)
Avatar of htang_us
htang_us

let say the format of abbrev.xml format is like this:

<ListOfWords>
<Word>Mr.</Word>
<Word>Ms.</Word>
</ListOfWords>

Then you can do this

<xsl:template match="document('../abbrev.xml')//ListOfWords/Word"> <!-- here you loop through all the words -->
<xsl:if test="$normArg=."> <!-- here make sure you compare the end of string -->
<xsl:value-of select="$normArg"/>
</xsl:if>
</xsl:template>
Avatar of jmc430
jmc430

ASKER

how do i compare the end of string?  i tried doing this $normArg[last()] but it did not work.

i cannot use

<xsl:template match="document('....

due to configuration settings i cannot use template match="document" but i can do comparisons using the document keyword.

thanks so much for helping me..


Avatar of htang_us
htang_us

about loop

try this

<xsl:for-each select="document('../abbrev.xml')//ListOfWords/Word">
<!-- compare the end of string -->
<xsl:if test="substring($normArg, string-length($normArg)-string-length(.))=.">
...
</xsl:if>
</xsl:for-each>

Avatar of jmc430
jmc430

ASKER

that doesn't work ...  (<xsl:if test="substring($normArg, string-length($normArg)-string-length(.))=.">)
Avatar of htang_us
htang_us

how about this
<xsl:if test="substring($normArg, string-length($normArg)-string-length(.))=node()">
Avatar of jmc430
jmc430

ASKER

that didn't work either
Avatar of htang_us
htang_us

test result is false or you got run-time error?
Avatar of jmc430
jmc430

ASKER

it's generating a TRUE value, but it's not getting the last word of the sentence
Avatar of jmc430
jmc430

ASKER

This is my sample XML file (one element):

<abbreviations>
<abbrev>IX.</abbrev>
<abbreviations>

This is my sample function:

<xsl:template name="removeTrailingDot">
        <xsl:param name="argument"/>
        <xsl:param name="normArg" select="normalize-space($argument)"/>

        <xsl:choose>
            <xsl:when test="substring($normArg, string-length($normArg), 1) = '.'">
                 <xsl:for-each select="document('../strulink.xml')//abbreviations/abbrev">
                      <xsl:if test="substring($normArg, string-length($normArg)-string-length(.))=node()">
                           <xsl:value-of select="$normArg"/>                                <= NOT REACHING HERE
                      </xsl:if>
                 </xsl:for-each>
                <xsl:value-of select="substring($normArg, 1, string-length($normArg) - 1)"/>    <= This is outputted
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$normArg"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

I do not know what I am doing wrong ... for testing, I just wanted it to read this tag:

<TEXT>`Characterization' Sought IX.</TEXT>

and retain the trailing period after "IX", but remove it otherwise.

Thank you for helping me!

Jamie
Avatar of htang_us
htang_us

So you want to match the last word of sentence to the list of abbreviation or match the end of the sentence to the list of abbreviation?

Avatar of jmc430
jmc430

ASKER

The end of the sentence to the list of abbreviations.

More specifically, if the <TEXT> element reads:

<TEXT> Here is the letter for the Mrs. </TEXT>

"Mrs." is an abbreviation.  I will have the string "Mrs." in my XML document(../strulink.xml) file, and the <TEXT> element should be outputted like this:

"Here is the letter for the Mrs."

However, if the <TEXT> element reads:
 
<TEXT> Title of Document. </TEXT>

The <TEXT> element should be outputted like this:

"Title of Document" (since it is not an abbreviation)

Basically any word that is an abbreviation within the <TEXT> element should remain abbreviated.
Otherwise, if the word is NOT an abbreviation (i.e., just a period at the end of a string), the trailing period should be removed.
Avatar of htang_us
htang_us

from what i see, all the tests return false. ( <= NOT REACHING HERE )

try this: output the end of sentence for each sentence, then compare if anyone of them matches the list of abbreviation.


        <xsl:choose>
            <xsl:when test="substring($normArg, string-length($normArg), 1) = '.'">
                 <xsl:for-each select="document('../strulink.xml')//abbreviations/abbrev">
                      <xsl:value-of select="substring($normArg, string-length($normArg)-string-length(.))"/>
                 </xsl:for-each>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$normArg"/>
            </xsl:otherwise>
        </xsl:choose>
 
Jaimee,

I see two questions in this question
1. how to create a list for protection against the removeTrailingDot
2. how to pick the last word in a sentence

2. has been solved in your other question

1. I don't think looping over the Word elements in the abbrev.xml is the right solution
you could just use XPath to solve this for you
in the following example $strParam is your last word

                <xsl:choose>
                    <xsl:when test="not(document('abbrev.xml')//ListOfWords[Word = $strParam])">
                        <xsl:call-template name="removeTrailingDot">
                            <xsl:with-param name="argument" select="$strParam"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$strParam"/>
                    </xsl:otherwise>
                </xsl:choose>

This works fine for me.
I recommend you to drop the loop approach!
What puzzles me is that you can use the document('') function,
but that you can't use mapping....

anyway,
if you paste the above code in the template for finding the last word from your other question,
this is what you get

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <xsl:call-template name="getLastWord">
            <xsl:with-param name="strParam" select="normalize-space(//TEXT)"/>
        </xsl:call-template>
        </xsl:template>
    <xsl:template name="getLastWord">
        <xsl:param name="strParam"/>
        <xsl:choose>
            <xsl:when test="contains($strParam, ' ')">
                <xsl:call-template name="getLastWord">
                    <xsl:with-param  name="strParam" select="substring-after($strParam, ' ')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:choose>
                    <xsl:when test="not(document('abbrev.xml')//ListOfWords[Word = $strParam])">
                        <xsl:call-template name="removeTrailingDot">
                            <xsl:with-param name="argument" select="$strParam"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$strParam"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
   
    <xsl:template name="removeTrailingDot">
        <xsl:param name="argument"/>
        <xsl:param name="normArg" select="normalize-space($argument)"/>
        <xsl:choose>
            <xsl:when test="substring($normArg, string-length($normArg), 1) = '.'">
                <xsl:value-of select="substring($normArg, 1, string-length($normArg) - 1)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$normArg"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
   
</xsl:stylesheet>

cheers


Avatar of jmc430
jmc430

ASKER

Hi Geert!

Wow . .thanks so much for helping me!!

I actually only wanted to extract the last word of the sentence because I wanted to use it to compare against the abbrev.xml file.

Is it possible to compare the last word of the sentence to the list of abbreviations in the abbrev.xml file, and extract the ENTIRE sentence with/without the trailing period, depending on whether or not it is an abbreviation?

When I am using the functionality you provided, only the last word is currently being returned, with/without the trailing period, but not the entire contents within the <HEAD> tag.

Thank you so much again Geert!!  
Jamie,

I now see,
passing the full string seems the cleanest to me

<?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/">
            <xsl:call-template name="getLastWord">
                <xsl:with-param name="strParam" select="normalize-space(//TEXT)"/>
                <xsl:with-param name="strFull" select="normalize-space(//TEXT)"/>
            </xsl:call-template>
        </xsl:template>
        <xsl:template name="getLastWord">
            <xsl:param name="strParam"/>
            <xsl:param name="strFull"/>
            <xsl:choose>
                <xsl:when test="contains($strParam, ' ')">
                    <xsl:call-template name="getLastWord">
                        <xsl:with-param  name="strParam" select="substring-after($strParam, ' ')"/>
                        <xsl:with-param name="strFull" select="$strFull"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:choose>
                        <xsl:when test="not(document('abbrev.xml')//ListOfWords[Word = $strParam])">
                            <xsl:call-template name="removeTrailingDot">
                                <xsl:with-param name="argument" select="$strFull"/>
                            </xsl:call-template>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$strFull"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
       
        <xsl:template name="removeTrailingDot">
            <xsl:param name="argument"/>
            <xsl:param name="normArg" select="normalize-space($argument)"/>
            <xsl:choose>
                <xsl:when test="substring($normArg, string-length($normArg), 1) = '.'">
                    <xsl:value-of select="substring($normArg, 1, string-length($normArg) - 1)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$normArg"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
       
    </xsl:stylesheet>
ASKER CERTIFIED SOLUTION
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of jmc430
jmc430

ASKER

Thank you so much Geert!  You are amazing
you are welcome Jamie
XML
XML

Extensible Markup Language (XML) refers to the encoding of documents such that they can be read by both machines and humans. XML documents use tags to show the beginning and end of a set of data. XML is used extensively on websites to show volumes of data, and is the default for a number of office productivity suites. This topic includes discussions of XML-related technologies, such as XQuery (the XML Query language), XPath (the XML Path language), XSLT (eXtensible Stylesheet Language Transformations), XLink (the XML Linking language) and XPointer (the XML Pointer language).

22K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo