Solved

replacing and parsing xml message

Posted on 2013-06-20
23
303 Views
Last Modified: 2013-06-24
I have the following xml input

<CommandRS>
 <Response>MI - COLLECT OPTIONAL FEES
&lt;X&gt; X IF SAME
                            &lt;CAD&gt;
&lt; &gt; NAMEID&lt;1.1  &gt; &lt;  &gt;
FEE CODE&lt;438&gt;  ANCILLARY SEAT FEE      FEE AMT&lt;   15.00&gt;
TKT NBR&lt;838574006&gt;CPN&lt;01&gt;FLT 1141 DTE 07AUG BRDOFF MIAYYZ
 TAXES &lt;       &gt; &lt;   &gt; &lt;       &gt; &lt;   &gt; &lt;       &gt; &lt;   &gt;
&lt; &gt; NAMEID&lt;     &gt;                                  SEG NBR&lt;  &gt;
 </Response>
</CommandRS>


And I want to replace &lt; with "<" and &gt; with ">". So then this looks like

<CommandRS>
 <Response>MI - COLLECT OPTIONAL FEES
<X> X IF SAME
                            <CAD>
< > NAMEID<1.1  > <  >
FEE CODE<438>  ANCILLARY SEAT FEE      FEE AMT<   15.00>
TKT NBR<838574006>CPN<01>FLT 1141 DTE 07AUG BRDOFF MIAYYZ
 TAXES <       > <   > <       > <   > <       > <   >
< > NAMEID<     >                                  SEG NBR<  >
 </Response>
</CommandRS>

I then want to remove any free text that is not inside the <> (while maintaining the spaces within the <> if any found). So that the final output is

<CommandRS>
 <Response>
<X><CAD>< ><1.1  ><  ><438> <   15.00><838574006><01><       ><   ><       ><   ><       ><   >< > <     > <  >
 </Response>
</CommandRS>


i'm feeding this input xml into an *.xsl
Please assist.
0
Comment
Question by:badtz7229
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 12
  • 11
23 Comments
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39263742
The easiest way to do this is using the infamous disable-output-escaping

Note that d-o-e is not a mandatory functionality from the XSLT spec,
so processors can rightfully escape from its implementation
(firefox browser XSLT does not support it for instance)

this is what you should do
<xsl:value-of select="Response" disable-output-escaping="yes"/>
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39263784
By the way, can you put XSLT questions in the XSLT zone, or give an indication in the title? I just coincidentally did not skip the question
0
 

Author Comment

by:badtz7229
ID: 39263854
I can never find that group when I'm submitting my question. That's why I always just place in CSS/XML.
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!

 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39263888
ah OK, did the d-o-e tric work?
0
 

Author Comment

by:badtz7229
ID: 39263906
Yes, the disable-output-escaping worked.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39263910
ah great

use it sparsely, because it is a bad serialisation trick,
and it could trigger you to build trees in a non conventional way
0
 

Author Comment

by:badtz7229
ID: 39264092
and how can i resolve the second question:

"I then want to remove any free text that is not inside the <> (while maintaining the spaces within the <> if any found). So that the final output is
<CommandRS>
 <Response>
<X><CAD>< ><1.1  ><  ><438> <   15.00><838574006><01><       ><   ><       ><   ><       ><   >< > <     > <  >
 </Response>
</CommandRS>
"
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39264134
ah, you basically only want the text inside the '<...>'?

Which XSLT processor are you using?
You would either need a recursive substring algoritm in XSLT1
or some regex stuff in XSLT2
The second one is a whole bunch easier, so it would help if we could use XSLT2 (Saxon 9 that is)
0
 

Author Comment

by:badtz7229
ID: 39264180
i believe xslt2.
0
 

Author Comment

by:badtz7229
ID: 39264181
yes, the text inside <..>
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39264302
For XSLT2, this will do the trick

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
    <xsl:template match="Response">
        <xsl:copy>
            <xsl:analyze-string select="." regex="(&lt;[^&gt;]*&gt;)">
                <xsl:matching-substring>
                    <xsl:value-of disable-output-escaping="yes" select="regex-group(1)"></xsl:value-of>
                </xsl:matching-substring>
            </xsl:analyze-string>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

Open in new window

0
 

Author Comment

by:badtz7229
ID: 39265919
Gertone:

That's giving me the following warning:
"xsl:analyze-string cannot be a child of the xsl:copy element. "
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39265994
well, code was tested,
never seen that warning before, but essentialy I believe that means you don't have an XSLT2 processor
Let me check
0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 39266170
Try this

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:template match="Response">
        <xsl:copy>
            <xsl:call-template name="strip-between-tags">
                <xsl:with-param name="str" select="."/>
            </xsl:call-template>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template name="strip-between-tags">
        <xsl:param name="str"/>
            <xsl:if 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:if>
    </xsl:template>    
</xsl:stylesheet> 

Open in new window

0
 

Author Comment

by:badtz7229
ID: 39266181
Im using visual studio 2008 , where i have the .xsl file and as input the xml . that's how i'm debugging it.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39266195
Ah, visual studio uses msxml and that only has XSLT1.
The most recent XSLT will do what you need

I did test with some XSLT1 processors to see what the feedback was on the XSLT2 stylesheet
and I got various messages, I did not test msxml, but the XSLT 1 solution I gave is generic
0
 

Author Comment

by:badtz7229
ID: 39266637
is it such that your snippet will not work for msxml ?
you mentioned earlier that in that case there was a recursive method option
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39266651
I am not sure you have seen all my posts.

#a39264302 is an XSLT2 solution to your problem which will not work using msxml

#a39266170 is the recursive XSLT1 solution that is generic and will work in each XSLT1 processor that supports d-o-e (including msxml)
0
 

Author Comment

by:badtz7229
ID: 39266905
Gertone,
that last code worked perfectly, it replaced the gt lt command and parse the string .

may i ask that you please explain what this code does.why do you have the
disable-output-escaping associated to "&lt" and not the entire node as when
<xsl:value-of select="Response" disable-output-escaping="yes"/> ?
0
 

Author Comment

by:badtz7229
ID: 39266959
So the output returns
<Response><X><CAD>< ><1.1  ><  ><438><   15.00><838574006><01><       ><   ><       ><   ><       ><   >< ><     ><  ></Response>

which is great. how can end the parsing with an <X>?  such that
<Response><X><CAD>< ><1.1  ><  ><438><   15.00><838574006><01><       ><   ><       ><   ><       ><   >< ><     ><  ><X></Response>
0
 

Author Comment

by:badtz7229
ID: 39267059
Sorry for asking many questions, I'm just trying to familiarize myself with this.
Now that the output gets parsed successfully, why am I unable to add an attribute? for example


      <xsl:attribute name="Version">
        <xsl:text>XML1.0.1</xsl:text>
      </xsl:attribute>

        
I get "An item of type 'Attribute' cannot be constructed within a node of type 'Root'."

I want to response to read
<CommandRQ Version="2003A.TsabreXML1.0.1">
 <Request>
<X><CAD>< ><1.1  ><  ><438> <   15.00><838574006><01><       ><   ><       ><   ><       ><   >< > <     > <  ><X>
 </Request>
</CommandRQ>
0
 

Author Closing Comment

by:badtz7229
ID: 39272577
thank you.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39272683
welcome,

seems I missed a couple of follow up over the weekend.

Your last question... I assume you were trying to add the attribute to the document root, not the root element. I think I showed a good way in your other question

Your second I did not get. Do you want to add a <X> after the parsing, or do you want the parsing to end when it hits a <X>?

First. Well, the d-o-e disables the escaping forcing a &lt; in the output to become a real <
but it is only necessary on the '<' and '>' not on what is inside.
0

Featured Post

Technology Partners: 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!

Question has a verified solution.

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

Suggested Solutions

I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
In this tutorial viewers will learn how to style transparent/translucent elements using alpha transparency in CSS Start with a normal styled element, such as a div.: Define its "background-color" property as "rgba (255, 255, 255, .5): The numbers in…
In this tutorial viewers will learn how to embed custom externally-hosted Google Fonts using the Google Font API in CSS Go to the Google Fonts website at google.com/fonts: Browse or search based on font properties or name to find a suitable font for…

734 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