XSL: replacing empty space with known value

I have the following xml input

sample 1:
<root>      
      <SeatElementNumber>1</SeatElementNumber>
      <CommandRS>
            <Response>MI&lt;X&gt;TKT NBR&lt;             &gt;</Response>
      </CommandRS>
      <Create>...       </Create>
</root>

sample 2:
<root>      
      <SeatElementNumber>1</SeatElementNumber>
      <CommandRS>
            <Response>MI&lt;X&gt;TKT NBR&lt;1234&gt;</Response>
      </CommandRS>
      <Create>...       </Create>
</root>

      

I currently have code which will extract the values between the lt and gt in order to build a Request xml as follows:
      <CommandRQ><Request><X><1234></Request></CommandRQ>

However, if the the TKT NBR in the input is null (like in sample 1), i want to use the tktNumber i stored in a prior variable. How can i do this in xsl?
This is code I have so far.

    <xsl:key  name="TktMatch"  match="View/Identify/Info[TicketNumber/@Status='TICKETED']/SegmentElementNumber"   use="." />      
    <xsl:variable name="SeatSegment" select="/root/Create/Other/Seat[position() = 1]/SegmentIDRef"/>    
    <xsl:variable name="TktNumber" select="key('TktMatch', $SeatSegment)/@TicketNumber"/>
       
    <xsl:template match="CommandRS">
            <xsl:apply-templates/>
        </CommandRQ>
    </xsl:template>
          
    <xsl:template match="Response">
        <Request>
            <xsl:call-template name="strip-between-tags">
                <xsl:with-param name="str" select="."/>
            </xsl:call-template>
        </Request>
    </xsl:template>

    <xsl:template name="strip-between-tags">
        <xsl:param name="str"/>
        <xsl:choose>
            <xsl:when test="contains($str, '&lt;')">
                <xsl:text disable-output-escaping="yes">&lt;</xsl:text>
                <xsl:value-of select="substring-before(substring-after($str, '&lt;'), '&gt;')"></xsl:value-of>
                <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                <xsl:call-template name="strip-between-tags">
                    <xsl:with-param name="str" select="substring-after($str, '&gt;')"/>
                </xsl:call-template>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
badtz7229Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Geert BormansInformation ArchitectCommented:
Assuming the ticket number si always the second tag
(meaning you also need to pass the depth)

   <xsl:template match="Response">
        <Request>
            <xsl:call-template name="strip-between-tags">
                <xsl:with-param name="str" select="."/>
                <xsl:with-param name="deep" select="1"/>
            </xsl:call-template>
        </Request>
    </xsl:template>
    
    <xsl:template name="strip-between-tags">
        <xsl:param name="str"/>
        <xsl:param name="deep"/>
        <xsl:choose>
            <xsl:when test="contains($str, '&lt;')">
                <xsl:text disable-output-escaping="yes">&lt;</xsl:text>
                <xsl:variable name="this-tag-content" select="substring-before(substring-after($str, '&lt;'), '&gt;')"></xsl:variable>
                <xsl:choose>
                    <xsl:when test="$deep = 2 and not(normalize-space($this-tag-content))">
                        <xsl:value-of select="$TktNumber"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$this-tag-content"></xsl:value-of>
                    </xsl:otherwise>
                </xsl:choose>
                <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                <xsl:call-template name="strip-between-tags">
                    <xsl:with-param name="str" select="substring-after($str, '&gt;')"/>
                    <xsl:with-param name="deep" select="$deep + 1"/>
                </xsl:call-template>
            </xsl:when>
        </xsl:choose>
    </xsl:template> 

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
badtz7229Author Commented:
Gertone,
your code worked (thanks) but when I execute the xsl (using Visual Studios) it seems to be returning the values that are in the <Create> node

The reponse builds as follows

   <CommandRQ><Request><X><1234></Request></CommandRQ>
                  2
                        
                              1
                              82D
                        
                  
                  
                        
                              1
                              2
                              RA
                              
                                    SRT
                                    SEAT
                              
                              
                              Pre-reserved Seating
                              82D
0
Geert BormansInformation ArchitectCommented:
well, that is standard processing,
All I changed was the named template and calling it,

This is a context processing issue that must have been there before
(I could not see full context of XSLT nor source XML)

There are a number of things you can do

If you never need to process the create, add an empty template for it
<xsl:template match="Create"/>

Or process the request from a higher level

instead of

<xsl:template match="Response">
        <Request>
            <xsl:call-template name="strip-between-tags">
                <xsl:with-param name="str" select="."/>
                <xsl:with-param name="deep" select="1"/>
            </xsl:call-template>
        </Request>
    </xsl:template>

do

<xsl:template match="CommandRS">
        <Request>
            <xsl:call-template name="strip-between-tags">
                <xsl:with-param name="str" select="Response"/>
                <xsl:with-param name="deep" select="1"/>
            </xsl:call-template>
        </Request>
    </xsl:template>
0
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

badtz7229Author Commented:
I have
      
    <xsl:template match="CommandRS">
        <CommandRQ>
            <xsl:apply-templates/>
        </CommandRQ>
    </xsl:template>
      
    <xsl:template match="Response">
        <Request>
            <xsl:call-template name="strip-between-tags">
                <xsl:with-param name="str" select="."/>
              <xsl:with-param name="deep" select="1"/>
            </xsl:call-template>
        </Request>
    </xsl:template>      
      
      
      
    <xsl:template name="strip-between-tags">
        <xsl:param name="str"/>
        <xsl:param name="deep"/>
            .....
    </xsl:template>
0
Geert BormansInformation ArchitectCommented:
simply add this one

<xsl:template match="Create"/>

and you likely want to add one for the SeatElementNumber too

<xsl:template match="SeatElementNumber"/>
0
badtz7229Author Commented:
I do need <Create> in order to get $TktNumber and i processed at a higher level, but it still shows all data from the <Create>
0
badtz7229Author Commented:
<xsl:template match="Create"/>
<xsl:template match="SeatElementNumber"/>

that worked.
but why is it necessary to include that, i dont' understand?
0
Geert BormansInformation ArchitectCommented:
Please send me the full XSLT you have and a full XML source
0
Geert BormansInformation ArchitectCommented:
Ignore previous message

The default processing for each element is "show the text" (I am cutting corners here)

By adding a template that says "do nothing" the nodes won't be processed

An alternative to adding two empty templates would be to be very explicit in what to process
eg. use a select in the apply templates of the parent of CommandRS
(that is root in the examples above, but not in your real XML I believe)

in that template do
<xsl:apply-templates select="CommandRS"/>
instead of
<xsl:apply-templates/>

without the select attribute apply-templates means: process child nodes
with the select attribute it means: from this point on (relative XPath) process the nodes in the @select
0
badtz7229Author Commented:
Thanks for ur help and explanation
0
Geert BormansInformation ArchitectCommented:
welcome
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
CSS

From novice to tech pro — start learning today.