Solved

replacing and parsing xml message

Posted on 2013-06-20
23
295 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
  • 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
 
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
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

So you have coded your own WordPress plugin and now you want to allow users to upload images to a folder in the plugin folder rather than the default media location? Follow along and this article will show you how to do just that!
Building a website can seem like a daunting task to the uninitiated but it really only requires knowledge of two basic languages: HTML and CSS.
In this tutorial viewers will learn how to define a gradient in CSS. Create a new HTML document with an internal stylesheet.: Create a div in CSS and name it Gradient. Define the background as "linear-gradient(to right, #ee3668, black)". Ensure you …
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…

919 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