Solved

XSLT value for State should match list of States, AL, AK,AZ,AR,CA, etc.

Posted on 2003-10-29
10
587 Views
Last Modified: 2008-03-06
I am trying to add some code to my xsl stylesheet that will check the value (in the XML) for the "State" node and if it doesn't match the list of states, I will show an error message in the html output.
0
Comment
Question by:rcheney
  • 6
  • 3
10 Comments
 

Author Comment

by:rcheney
ID: 9647634
How do I go about comparing the users input for the "State" value against a list of all the acceptable two-letter values for the fifty states?  Do I do this with template-match type of thing or with contains($State, "AK|AL|CA|MN")  etc.
Or is there something with Match? or pattern match?   I have the list of states and I can compare the State value with one state at a time.  Should I use some sort of   for-each  statement?
Thanks in advance for any clues pointing me in the right general direction.
0
 
LVL 15

Expert Comment

by:dualsoul
ID: 9648998
>Do I do this with template-match type of thing or with contains($State, "AK|AL|CA|MN")  
if it suite you , why not? i think it's the most straightforward and simple way.

<xsl:for-each select="user[@State='AK|AL|CA|MN']> - will select all users with state within AK AL CA MN
assuming you have xml like this:
       <user State="AK">
..............

also you can use extension-function, written in some language like Java, that will do comparsion.

0
 

Author Comment

by:rcheney
ID: 9650377
contains($State, "AK|AL|CA|MN") doesn't work because the "pipe" separator is not recognized as meaning "or".  It just looks at the entire AK|AL|CA|MN as one block of text to search the string for.

Will    for-each  cycle through node 'values'  or just the nodes themselves?  As I am processing each "State" node, I need to check the value to see if it matches AK|AL|CA|MN   etc.
0
 
LVL 15

Expert Comment

by:dualsoul
ID: 9650421
contains() - hm...i don't remember wha't this? one of XPath function?
i mean your own extension-function, not one from XSLT


>Will    for-each  cycle through node 'values'  or just the nodes themselves?  As I am processing each "State" node, I >need to check the value to see if it matches AK|AL|CA|MN   etc.

so i assuming you are using somethink like this (or post your code here):

<xsl:template match="State">
..................................
<!-- test for State value -->
         <xsl:if test=".='AK|AL|CA|MN'">
                     ....test match....
         </xsl:if>
</xsl:template>

0
 

Author Comment

by:rcheney
ID: 9650795
I tried the code below, but not in a template, just in the middle of my xsl stylesheet when processing the node. It works if the value for the node is AK and I only have ='AK' but when I add more states example: ='AK|AL|MN',  it doesn't look at it as AK or AL or MN it just seems to think I am checking for a string like "AK|AL|MN".   Would it work differently if I do the checking in a template, instead of the way I am doing it?  

<xsl:if test="ownershipDocument/reportingOwner/reportingOwnerAddress/rptOwnerState='MN|AK'">
                     ....test match....
         </xsl:if>
0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 

Author Comment

by:rcheney
ID: 9650976
I just tried using "or" instead of the "pipe" character and it looks like it might work.

..........Instead of...........
<xsl:if test="ownershipDocument/reportingOwner/reportingOwnerAddress/rptOwnerState='MN|AK'">
                ....test match....
</xsl:if>

............like this instead............. with   'or'

<xsl:if test="ownershipDocument/reportingOwner/reportingOwnerAddress/rptOwnerState='MN' or 'AK' or 'AL'">
                     ....test match....
         </xsl:if>
0
 

Author Comment

by:rcheney
ID: 9651144
I was wrong, 'AK' or 'AL'    etc.  does not work.  It just reports a "match" even if the State value does not match the list.
0
 
LVL 15

Expert Comment

by:dualsoul
ID: 9652990
or sorry....
insted of : test=".='AK|AL|CA|MN'", try this:

   test= ".='AK'|'AL'|'CA'|'MN'"

0
 
LVL 6

Accepted Solution

by:
PeterCiuffetti earned 200 total points
ID: 9653233
The contains goes the other way.  You want to look for your state in a list of known state values this way.  Put it in a variable, put delimiters on it and then check...

contains('|AL|AK|AZ|AR|CA|CO|CT|DE|DC|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY|',concat('|',$theState,'|'))

Here's a solution that corrects case, checks length and returns a message indicating valid or not.  Given the test document...

<test>
      <state>MA</state>
      <state>Me</state>
      <state>AK</state>
      <state>A</state>
      <state>Al</state>
      <state>AX</state>
      <state>AZ</state>
</test>

And the stylesheet...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="test">
      <result>
            <xsl:for-each select="state">
                  <state>
                        <xsl:call-template name="checkState">
                              <xsl:with-param name="theState" select="translate(.,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQURSTUVWXYZ')"/>
                        </xsl:call-template>
                  </state>
            </xsl:for-each>
      </result>
</xsl:template>

<xsl:template name="checkState">
      <xsl:param name="theState"/>

      <xsl:choose>
            <xsl:when test="string-length($theState) != 2">
                  <xsl:value-of select="$theState"/>
                  <xsl:text> is not a valid state abbreviation</xsl:text>
            </xsl:when>
            <xsl:when test="contains('|AL|AK|AZ|AR|CA|CO|CT|DE|DC|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY|',concat('|',$theState,'|'))">
                  <xsl:value-of select="$theState"/>
                  <xsl:text> is a valid state abbreviation</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                  <xsl:value-of select="$theState"/>
                  <xsl:text> is not a valid state abbreviation</xsl:text>
            </xsl:otherwise>
      </xsl:choose>
</xsl:template>

</xsl:stylesheet>

It will produce the following output...

<result>
  <state>MA is a valid state abbreviation</state>
  <state>ME is a valid state abbreviation</state>
  <state>AK is a valid state abbreviation</state>
  <state>A is not a valid state abbreviation</state>
  <state>AL is a valid state abbreviation</state>
  <state>AX is not a valid state abbreviation</state>
  <state>AZ is a valid state abbreviation</state>
</result>
0
 

Author Comment

by:rcheney
ID: 9673799
Thank You Peter, for the fabulous answer.  It took me awhile to respond because it took me awhile to adjust the code to fit my existing stylesheet and then test it.  I am just starting to figure out how to use templates and template-match, etc.
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction In my previous article (http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SSIS/A_9150-Loading-XML-Using-SSIS.html) I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
The Confluence of Individual Knowledge and the Collective Intelligence At this writing (summer 2013) the term API (http://dictionary.reference.com/browse/API?s=t) has made its way into the popular lexicon of the English language.  A few years ago, …
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
A short film showing how OnPage and Connectwise integration works.

932 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now