【问题标题】:XML::Simple and namespacesXML::Simple 和命名空间
【发布时间】:2020-04-27 09:54:20
【问题描述】:

注意:问题已解决,但请阅读下面 ikegami 的回复。信息量非常大,尤其是关于避免使用 XML::Simple 的链接。

我刚开始与一家广泛使用 XML::Simple 的公司合作,我们现在遇到了解析问题。

这是一个示例 XML 文件...(注意第一部分已注释掉)

<xyz:CostFee>
        <ec:OPA>25.00</ec:OPA>
        <ec:CTID>278421</ec:CTID>
        <xyz:CDEPSID>82</xyz:CDEPSID>
        <ec:IID>8765654</ec:IID>
</xyz:CostFee>

我正在使用这个简单的 perl 脚本 ....

#!/usr/bin/perl

use XML::Simple;
use Data::Dumper;

my $content = XMLin('./data.xml');
print Dumper($content);

运行脚本会产生这个.....

Undeclared prefix: xyz at /System/Library/Perl/Extras/5.18/XML/NamespaceSupport.pm line 298.
XML::Simple called at ./xml_test.pl line 6.

当我在 XML 文件中使用它时...

<catalog>
        <part partnum="184324" desc="Desc 1" price="19.00" />
        <part partnum="765398" desc="Desc 2" price="18.00" />
        <part partnum="878998" desc="Desc 3" price="15.00"/>
</catalog>

它工作得很好,Dumper 很高兴地把它扔掉了.....

由于我们讨论的是遗留程序并且不需要替换 XML::Simple(但老实说,我认为您不能在 XML::Simple 中注册名称空间,但我绝不是专家)。

谁能用一两个指针给我指出正确的方向?我认为将命名空间信息作为 XML 内容的一部分可能是可行的方法,例如......

<xsl:stylesheet version="1.0" xmlns:xsl="https://www.w3.org/1999/XSL/Transform">

非常感谢JW

【问题讨论】:

  • 当你有foo:bar的关键节点时,命名空间是强制性的。请提供有效的 XML

标签: xml perl xml-parsing


【解决方案1】:

节点必须是具有以下属性的节点的子节点:

xmlns:xyz="..."

(尽管您应该 avoid XML::Simple,但如果您的 XML 无效,更改解析器将不起作用。)

例如改变

<doc>
   <xyz:CostFee>
      <ec:OPA>25.00</ec:OPA>
      <ec:CTID>278421</ec:CID>
      <xyz:CDEPSID>82</xyz:CDEPSID>
      <ec:IID>8765654</ec:IID>
   </xyz:CostFee>
</doc>

<doc xmlns:xyz="..." xmlns:ec="...">
   <xyz:CostFee>
      <ec:OPA>25.00</ec:OPA>
      <ec:CTID>278421</ec:CTID>
      <xyz:CDEPSID>82</xyz:CDEPSID>
      <ec:IID>8765654</ec:IID>
   </xyz:CostFee>
</doc>

允许解析文档。 (注意添加了前缀声明,以及从 &lt;/ec:CTID&gt;&lt;/ec:CID&gt; 的更改。使用正确的 URN 代替 ...。)

【讨论】:

  • 我的解决方案是在后端使用 XML::Parser 而不是 XML::Sax,这解决了我的问题。您提供的关于避免 XML::Simple 的链接提供了 SO 信息,我计划以此作为完全摆脱它的理由。我非常感谢池上。 JW
  • XML::Simple+XML::Parser 组合不知道命名空间,因此将该组合与使用命名空间的文档一起使用是没有意义的。您必须硬编码前缀而不是命名空间,这是一个很大的禁忌。人们应该知道元素的命名空间,而不是使用什么前缀(如果有)来指示元素的命名空间。用于前缀的 id 没有意义,并且可以在文档之间有所不同,而不会影响架构合规性。
  • 例如,&lt;d xmlns="x"&gt;&lt;e/&gt;&lt;/d&gt;&lt;d foo:xmlns="x"&gt;&lt;foo:e/&gt;&lt;/d&gt;&lt;d bar:xmlns="x"&gt;&lt;bar:e/&gt;&lt;/d&gt; 是等效的文档,但 XML::Simple+XML::Parser 的解析方式不同。
  • 好吧,如果 XML::Simple+XML::Sax 和 XML::Simple+XML::Parser 都出现命名空间问题,那么 XML::LibXML 是如何成功的呢?只是想了解
  • [Summary] XML::Simple+XML::SAX with NSExpand =&gt; 1 不会出现命名空间问题。当然,您仍然会遇到使用 XML::Simple 的所有其他问题。使用该设置,您可以使用命名空间而不是您应该使用的前缀。 /// 你问的问题不是命名空间问题;这是无效的 XML。
【解决方案2】:

一行修复.... 只需设置

$XML::Simple::PREFERRED_PARSER = "XML::Parser".

在调用 XMLin 之前。

【讨论】:

    猜你喜欢
    • 2013-02-01
    • 1970-01-01
    • 2012-03-23
    • 2011-12-26
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多