Perl-libXML使用findnodes搜索默认名称空间



给定一个定义了多个名称空间的XML文件,使用XPath查询在DOM中搜索默认名称空间中的元素的最简单方法是什么?

正如标题所示,这是使用Perl和libXML。

此外,是否可以在不硬编码命名空间的情况下完成此操作(如果使用XPathContext定义命名空间,是否可以查询文件的默认命名空间(

我正在努力实现的目标:
我正在许多不同年龄的xlsx电子表格文档中搜索某些公式并进行处理。我只是想用一个简单的findnodes(//f)来收集每张纸上的所有公式。所有的表都定义了多个名称空间,但大多数元素似乎没有完全限定的名称空间。例如:

<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
<sheetData>
<row r="1">
<c r="A1">
<f>SUM(1+2)</f>
<v>3</v>
</c>
<c r="A2">
<f>SUM(4+5)</f>
<v>9</v>
</c>
...
<controls>
<mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<mc:Choice Requires="x14">
<control shapeId="1" r:id="rId4" name="blah">
...

正如我上面提到的,我只关心公式,即:在上面的例子中"SUM(1+2("one_answers"SUM(4+5("。

如何提取这些数据
解决方案不一定很漂亮,但必须始终有效(我不确定名称空间是否有很大变化。(

我可以通过grep/sed传输所有内容,但希望正确解析它不会太难。。。

使用local-name():可以完全忽略命名空间

...->findnodes('//*[local-name()="f"]')

请注意,总的来说,这不是最好的主意。例如,如果公式的语法取决于版本,并且您需要对它们进行规范化,则可以在每个命名空间中单独搜索公式,并根据命名空间运行不同的转换。

没有默认命名空间。默认值可能因标记而异。您实际上是在询问根元素的名称空间。您可能希望这样做以支持一些"足够相似"的格式,具体操作如下:

use XML::LibXML               qw( );
use XML::LibXML::XPathContext qw( );
my $doc = XML::LibXML->new->parse_string($xml);
my $root_ns = $doc->documentElement->namespaceURI;
my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs( xl => $root_ns );
$xpc->findnodes('//xl:f', $doc)

但是您没有提出任何不使用已知名称空间的理由。您应该简单地使用以下内容:

use XML::LibXML               qw( );
use XML::LibXML::XPathContext qw( );
my $doc = XML::LibXML->new->parse_string($xml);
my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs( xl => 'http://schemas.openxmlformats.org/spreadsheetml/2006/main' );
$xpc->findnodes('//xl:f', $doc)

最新更新