不完全なXMLファイルテキストから値を取得して変数に保存するにはどうすればよいですか?

不完全なXMLファイルテキストから値を取得して変数に保存するにはどうすればよいですか?

タグ内のXML値を簡単に取得できるように、不完全なXMLファイルを適切にタグ付きXMLにフォーマットするのに問題があります。

出力テキストは次のとおりです。

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>
----------------------------------------------

今2つのことをしたいと思います。

  1. この出力を ---------------- Recived -------------------- マーカーから最後まで切り、別の変数に保存します。

  2. 次に、正しいタグとすべてのエントリを含む完全なXMLファイルになるようにファイルをトリミングします。つまり、<?xml version="1.0" encoding="UTF-8"?>から</methodResponse>

私はSolarisサーバー上で上記の2つのタスクしか実行したいと思います。試してみましたが、xmllint --xpathxpathがパッケージにないようです。だから別の方法を提案してください。

答え1

正式な答えは - あなたは知らないです。破損したXMLは設計上致命的です。すべてのパーサー修理する定義によると、壊れたXMLもXMLパーサーではありません。

XMLを拒否し、「アップストリーム」にそのデータが破損していることを知らせる必要があります。なぜならそうです。 XMLを修正するためにハッキングを渡すことは、コードの長期的な安定性と信頼性に非常に悪いニュースであるため、これを非常に強力に推進してください。いつかはランダムに壊れることがあります。

つまり、XMLが壊れずにテキストファイルにカプセル化されただけです。宣言のようなものが欠けていますが、実際には正式に要求されるわけではありません。

だからあなたはこれを行うことができます:

#!/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;

あなた〜するXML::TwigXMLライブラリが必要です。広く利用可能であり、場合によってはデフォルトでインストールされるか、パッケージマネージャを通じて利用できるため使用しています。 (そうでない場合は、CPANからインポートできる必要があります。)

しかし、実際には必要ありません。print $xml使用したいツールで使用できる有効なXMLを提供します。

上記のソースデータが与えられると、次のように表示されます。

<?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>

関連情報