1

XML スプレッドシートとして保存された Excel ファイルのデータを処理しようとしています。かなりの量の調査を行った後 (私はこれまで XML 処理をあまり行ったことがありませんでした)、まだ機能させることができませんでした。これが私の最小限のファイルの内容です:

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40"
 xmlns:fn="http://www.w3.org/2005/xpath-functions"
 xmlns:sbmextension="http://www.serena.com/SBM/XSLT_Extension">
 <Worksheet ss:Name="index">
 </Worksheet>
</Workbook>

そして私のスクリプト:

use XML::LibXML;
use Data::Dumper;
my $filename = $ARGV[0];
my $parser = XML::LibXML->new();
my $doc    = $parser->parse_file($filename);
my $xc = XML::LibXML::XPathContext->new( $doc->documentElement );
my $xpath = '/Workbook/Worksheet/@ss:Name';

print Dumper $xc->findvalue($xpath);

ただし、(デフォルトの名前空間?) xmlns="urn:schemas-microsoft-com:office:spreadsheet" を削除すると、機能し始めます。私が欠けているものを教えてください。ドキュメントを解析する前にそれを削除することもできると思いますが、何が間違っていたのかを理解したいと思います:)。前もって感謝します。

4

1 に答える 1

3

XPath 式と名前空間を使用する場合は、最初に名前空間を登録してから、名前空間の要素が言及されているすべての XPath 式で毎回それを使用する必要があります。

#!/usr/bin/perl
use warnings;
use strict;

use XML::LibXML;
use Data::Dumper;

my $xml = << '__XML__';
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook
   xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40"
 xmlns:fn="http://www.w3.org/2005/xpath-functions"
 xmlns:sbmextension="http://www.serena.com/SBM/XSLT_Extension">
 <Worksheet ss:Name="index">
 </Worksheet>
</Workbook>
__XML__

my $doc = XML::LibXML->load_xml( string => $xml);
my $xc  = XML::LibXML::XPathContext->new( $doc->documentElement );
$xc->registerNs('ss', 'urn:schemas-microsoft-com:office:spreadsheet');
my $xpath = '/ss:Workbook/ss:Worksheet/@ss:Name';

print Dumper $xc->findvalue($xpath);
于 2013-04-08T12:24:00.690 に答える