Solved

replacing and parsing xml message

Posted on 2013-06-20
23
291 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
ah OK, did the d-o-e tric work?
0
 

Author Comment

by:badtz7229
Comment Utility
Yes, the disable-output-escaping worked.
0
 
LVL 60

Expert Comment

by:Geert Bormans
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
i believe xslt2.
0
 

Author Comment

by:badtz7229
Comment Utility
yes, the text inside <..>
0
 
LVL 60

Expert Comment

by:Geert Bormans
Comment Utility
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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

Author Comment

by:badtz7229
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
thank you.
0
 
LVL 60

Expert Comment

by:Geert Bormans
Comment Utility
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

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Creating a CSS block that only applies to printing By default, all of your CSS applies to every possible view of your page - whether on screen, printed, landscape, touch-screen, or whatever.  You can, however, add CSS that only applies under certai…
SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
In this tutorial viewers will learn how to style a corner ribbon overlay for an image using CSS Create a new class by typing ".Ribbon":  Define the class' "display:" as "inline-block": Define its "position:" as "relative": Define its "overflow:" as …
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…

771 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

10 Experts available now in Live!

Get 1:1 Help Now