-1

I am having an issue while formatting an incomplete XML file in to a proper tagged XML, so that I can easily fetch the XML value inside a tag from it.

Output text is like this:

Input parameters 
         User       : abcd
         User       : abc@1234
         User Agent : pqr Server/12.0/1.0
         file  Name : tmpfile.9133
         Timeout    : 5
         Nr  thread : 1
         Nr resends : 1
_____ Adresses:____
http://localhost:12345/Mrr
File tmpfile.9133 Contains  1  requests.
start thread 0
---------------- Sending --------------------
<methodCall>
<methodName>Test1</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>row1</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>main1</name>
<value>ADM</value>
</member>
<member>
<name>originTransactionID</name>
<value>464372231</value>
</member>
<member>
<name>min</name>
<value>99912345678</value>
</member>
<member>
<name>originTimeStamp</name>
<value>
<dateTime.iso8601>20150929T02:20:32+0300</dateTime.iso8601>
</value>
</member>
<member>
<name>main2</name>
<value>
<array>
<data>
<value>
<struct>
<member>
<name>ID</name>
<value>
<i4>115001</i4>
</value>
</member>
<member>
<name>ValueNew</name>
<value>
<string>0</string>
</value>
</member>
</struct>
</value>
</data>
</array>
</value>
</member>
<member>
<name>originHostName</name>
<value>rat</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>

---------------- Recived  --------------------
HTTP/1.1 200 OK
X-Powered-By: abc
Date: Mon, 28 Sep 2015 23:20:32 GMT
Server: xyz
Set-Cookie: JSESSIONID=15du5xtimqk42qoeej6o8l0u6;Path=/
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Length: 1489
Content-Type: text/xml

<?xml version="1.0" encoding="UTF-8"?><methodResponse><params><param><value><struct><member><name>fsdfsdfsdf</name><value><array><data><value><i4>536871492</i4></value></data></array></value></member><member><name>sdfsdfsdf</name><value><array><data><value><i4>0</i4></value></data></array></value></member><member><name>txnID</name><value><string>464372231</string></value></member><member><name>responseCode</name><value><i4>0</i4></value></member><member><name>info</name><value><array><data><value><struct><member><name>ID</name><value><i4>115001</i4></value></member><member><name>Value</name><value><string>0</string></value></member><member><name>Information</name><value><array><data><value><struct><member><name>ID</name><value><i4>11500101</i4></value></member><member><name>TSource</name><value><i4>3</i4></value></member><member><name>TValue</name><value><string>524288000</string></value></member></struct></value><value><struct><member><name>TID</name><value><i4>11500102</i4></value></member><member><name>TSource</name><value><i4>3</i4></value></member><member><name>TValue</name><value><string>519045120</string></value></member></struct></value></data></array></value></member></struct></value></data></array></value></member></struct></value></param></params></methodResponse>
----------------------------------------------

Now I want to perform 2 operations:

  1. make this output to be trim from the mark ---------------- Recived -------------------- till end and store it in a seperate variable.

  2. Then trim this file so that it is a perfect XML file with proper tags and all... i.e. starting from <?xml version="1.0" encoding="UTF-8"?> to </methodResponse>.

I want to do the above two tasks on Solaris server only. I tried using xmllint --xpath but seems like xpath is not in the package. So please suggest any other way.

1

The official answer is - you don't. Broken XML is fatal by design. Any parser that fixes broken XML is also - by definition - not an XML parser.

You should reject the XML and tell your 'upstream' that their data is corrupt - because it is. Push very hard on this, because a hacky bodge to forward fix XML is very bad news for long term stability and reliability of your code. It might one day just break randomly.

Having said that - your XML isn't broken - it's just wrapped up in a text file. And it's missing stuff like declarations, but that isn't actually formally required.

So you can do something like this:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;

my $xml; 
while ( <> ) { 
    if ( m/-- Sending --/ .. /-- Recived  --/ ) { 
        next if m/----/;  ##skip the sending/recived lines
        next if m/^\s*$/;   #skip any blank lines
        $xml .= $_; #add the current line to "$xml". 
    }
}

my $twig = XML::Twig -> new ( 'pretty_print' => 'indented_a' ) 
$twig -> parse ( $xml );
$twig -> set_encoding('utf-8');
$twig -> set_xml_version('1.0');
$twig -> print;

You will need an XML library - I've use XML::Twig because it's widely available and in some cases installed by default/available through your package manager. (You should be able to fetch it from CPAN if it isn't).

You don't actually need it though - the print $xml will give you valid XML that you can then use with whatever tool you were going to anyway.

This - given your source data as above - spits out:

<?xml version="1.0" encoding="utf-8"?>
<methodCall>
  <methodName>Test1</methodName>
  <params>
    <param>
      <value>
        <struct>
          <member>
            <name>row1</name>
            <value>
              <i4>1</i4>
            </value>
          </member>
          <member>
            <name>main1</name>
            <value>ADM</value>
          </member>
          <member>
            <name>originTransactionID</name>
            <value>464372231</value>
          </member>
          <member>
            <name>min</name>
            <value>99912345678</value>
          </member>
          <member>
            <name>originTimeStamp</name>
            <value>
              <dateTime.iso8601>20150929T02:20:32+0300</dateTime.iso8601>
            </value>
          </member>
          <member>
            <name>main2</name>
            <value>
              <array>
                <data>
                  <value>
                    <struct>
                      <member>
                        <name>ID</name>
                        <value>
                          <i4>115001</i4>
                        </value>
                      </member>
                      <member>
                        <name>ValueNew</name>
                        <value>
                          <string>0</string>
                        </value>
                      </member>
                    </struct>
                  </value>
                </data>
              </array>
            </value>
          </member>
          <member>
            <name>originHostName</name>
            <value>rat</value>
          </member>
        </struct>
      </value>
    </param>
  </params>
</methodCall>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.