[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 401
  • Last Modified:

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



0
jmc430
Asked:
jmc430
  • 12
  • 7
  • 6
1 Solution
 
htang_usCommented:
         <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
0
 
Geert BormansCommented:
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!
0
 
Geert BormansCommented:
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....
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
jmc430Author Commented:
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!

0
 
jmc430Author Commented:
Hi Geert!

Thanks for writing me back! :)

How can I use nodesets?

Thanks again for helping me!!


0
 
jmc430Author Commented:
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
0
 
jmc430Author Commented:
(the "document" function is indeed allowed)
0
 
htang_usCommented:
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>
0
 
jmc430Author Commented:
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..


0
 
htang_usCommented:
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>

0
 
jmc430Author Commented:
that doesn't work ...  (<xsl:if test="substring($normArg, string-length($normArg)-string-length(.))=.">)
0
 
htang_usCommented:
how about this
<xsl:if test="substring($normArg, string-length($normArg)-string-length(.))=node()">
0
 
jmc430Author Commented:
that didn't work either
0
 
htang_usCommented:
test result is false or you got run-time error?
0
 
jmc430Author Commented:
it's generating a TRUE value, but it's not getting the last word of the sentence
0
 
jmc430Author Commented:
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
0
 
htang_usCommented:
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?

0
 
jmc430Author Commented:
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.
0
 
htang_usCommented:
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>
 
0
 
Geert BormansCommented:
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


0
 
jmc430Author Commented:
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!!  
0
 
Geert BormansCommented:
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>
0
 
Geert BormansCommented:
Jamie,

just for the sake of the argument....
Here I made the same XSLT now with a look-up table.
Since the document('') works
why don't you try this for a minute
If it works, it is even cleaner, because it does not require a seperate file

cheers

<?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:map="urn:internal" exclude-result-prefixes="map">
        <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('')//map:ListOfWords[map: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>

        <map:ListOfWords>
            <map:Word>Mr.</map:Word>
            <map:Word>Ms.</map:Word>
        </map:ListOfWords>
       
    </xsl:stylesheet>
0
 
jmc430Author Commented:
Thank you so much Geert!  You are amazing
0
 
Geert BormansCommented:
you are welcome Jamie
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 12
  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now