1

私はWindows7マシンでPerlを使ってコーディングしています。以下のXPathコードを使用してXMLからデータを抽出できます

use strict;
use warning;

use XML::LibXML;

my $parser = XML::LibXML->new();
        my $doc    = $parser->parse_file($newfile);
        my $query  = "/tradenet/message/header/unique_ref_no/date/text( )";
        my($node)   = $doc->findnodes($query);
        $node->setData("$file_seq_number");  

ただし、別のXMLで同じコードを使用すると、2番目のドキュメントのxpathは次のようになります。

/TradenetResponse/OutboundMessage/out:OutwardPermit/out:Declaration/out:Header/cac:UniqueReferenceNumber/cbc:SequenceNumeric

Perlコードと合わせて、抽出コードは次のようになります。

my $parser = XML::LibXML->new();
    my $doc    = $parser->parse_file($newfile);
    my $query  = "/TradenetResponse/OutboundMessage/out:OutwardPermit/out:Declaration/out:Header/cac:UniqueReferenceNumber/cbc:SequenceNumeric/text( )";
    my($node)   = $doc->findnodes($query);
    $node->setData("$file_seq_number");

2番目のコードを使用すると、2番目のXMLからデータを取得できません。「Perl.plの5行目の未定義の値でメソッド「setData」を呼び出せません」というエラーが表示されます。

2番目のXPATHアドレスの「:」文字はコードに影響しますか?

4

1 に答える 1

5

XPathクエリが適切なノードを見つけるには、、、およびの意味outcac定義する必要があります。cbc

my $doc = $parser->parse_file($newfile);
my $xpath_context = XML::LibXML::XPathContext->new($doc->documentElement());

# These URIs need to be the same as the ones in the source document
$xpath_context->registerNs('out', 'http://example.com/out.xsd');
$xpath_context->registerNs('cac', 'http://example.com/cac.xsd');
$xpath_context->registerNs('cbc', 'http://example.com/cbc.xsd');

my $query  = "/TradenetResponse/OutboundMessage/out:OutwardPermit/out:Declaration/out:Header/cac:UniqueReferenceNumber/cbc:SequenceNumeric/text( )";
my ($node) = $xpath_context->findnodes($query);

約束通り、これが実際の例です。まず、テスト入力ファイル:

<?xml version="1.0"?>

<!-- input.xml -->

<TradenetResponse xmlns:a="http://example.com/out.xsd"
                  xmlns:b="http://example.com/cac.xsd"
                  xmlns:c="http://example.com/cbc.xsd">
  <OutboundMessage>
    <a:OutwardPermit>
      <a:Declaration>
        <a:Header>
          <b:UniqueReferenceNumber>
            <c:SequenceNumeric>1234</c:SequenceNumeric>
          </b:UniqueReferenceNumber>
        </a:Header>
      </a:Declaration>
    </a:OutwardPermit>
  </OutboundMessage>
</TradenetResponse>

そして、これが動作するPerlスクリプトです。

#!/usr/bin/perl

# parse.pl

use strict;
use warnings;
use XML::LibXML;

my $parser = XML::LibXML->new();

my $newfile = "input.xml";
my $doc = $parser->parse_file($newfile);
my $xpath_context = XML::LibXML::XPathContext->new($doc->documentElement());

# These URIs need to be the same as the ones in the source document
$xpath_context->registerNs('out', 'http://example.com/out.xsd');
$xpath_context->registerNs('cac', 'http://example.com/cac.xsd');
$xpath_context->registerNs('cbc', 'http://example.com/cbc.xsd');

# Query wrapped for clarity                                                                                                         
my $query = "/TradenetResponse/OutboundMessage/out:OutwardPermit" .
            "/out:Declaration/out:Header/cac:UniqueReferenceNumber" .
            "/cbc:SequenceNumeric/text()";

my ($node) = $xpath_context->findnodes($query);

print "Value: " . $node->getData() . "\n";

私の出力は次のとおりです。

sean @ localhost:〜xmltest $ ./parse.pl
値:1234
于 2012-08-21T17:02:37.697 に答える