【问题标题】:read xml file without any XML module读取没有任何 XML 模块的 xml 文件
【发布时间】:2015-07-27 10:56:01
【问题描述】:

我正在尝试使用 Perl 读取 XML 表单,但我无法使用任何 XML 模块,例如 XML::Simple、XML::Parse。

这是一个简单的 XML 表单,包含一些基本信息和一个 MS Doc 附件。 我想阅读这个 XML 并下载这个附加的 Doc 文件,然后在屏幕上打印 XML 信息。

但我不知道如何做到这一点没有 XML 模块,我听说 XML 文件可以使用 Data::Dumper 进行解析,但我对这个模块不熟悉,所以不知道怎么做。

如果没有 XML 模块,你能帮我解决这个问题吗?

示例 XML:

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
   </book>
</catalog>

【问题讨论】:

  • 解析 XML 远非简单。这就是为什么有模块和库可以做到这一点。我无法想象你在想什么,但是Data::Dumper不能这样使用;在任何情况下它都是一个模块,你不能使用它们。为什么不能使用模块?你能展示你的数据样本吗?
  • 我希望我知道人们为什么这样做。这是一个不必要和无用的限制。我想你可以看看XML::Parser::Lite 并复制这些想法。请出示您的数据好吗?
  • 看,认真的。 XML 很复杂。解析它并非易事。这就是解析器存在的原因——因为它们确保事情以有效、干净和流畅的方式发生。在没有 XML 解析器的情况下解析 XML 有点像用牙刷清洁马桶。你可以做到,但它比它需要的更难,而且有点脏。但是,就目前而言,这个问题是“我如何编写 XML 解析器”,所以我建议 - 太宽泛,无法有意义地回答。
  • 是的,您可以使用解析器...
  • 请不要更改您的问题。特别是如果你已经有了答案。如果您想问其他问题,请将其作为一个新问题提出。

标签: xml perl xml-parsing perl-module


【解决方案1】:

我想重申这是一个坏主意。因为虽然 XML 看起来 像纯文本 - 它是 不是 纯文本。如果你这样对待它,你正在创建脆弱、不可维护和不可支持的代码,这很可能有一天会崩溃,因为有人以有效的方式更改了 XML 格式。

我强烈建议您首先访问您的项目,并指出在没有 XML 解析器的情况下解析 XML 就像尝试使用锤子将螺丝钉入木头一样。在这方面它有点工作,但结果相当粗制滥造,坦率地说,这是完全没有必要的,因为存在螺丝刀,它们可以正确、轻松地完成工作,并且可以广泛使用。

例如

您能告诉我如何使用 XML 模块打印上述 XML 文件的每个图书 ID 的作者、标题和价格吗?

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

use XML::Twig;
my $twig = XML::Twig -> new -> parsefile ( 'your_file.xml' );
foreach my $book ( $twig -> get_xpath ( '//book' ) ) {
    print join ("\n", 
         $book -> att('id'),
         $book -> field('author'),
         $book -> field('title'),
         $book -> field('price'), ),"\n----\n";
}

但是:

鉴于您的非常具体示例,您可能能够将其视为“纯文本”而侥幸逃脱。在您执行此操作之前,您应该向您的项目负责人指出这是一种冒险的方法 - 您正在用锤子拧螺丝 - 因此会产生持续存在的支持问题风险,而这微不足道已解决只需安装一些免费可用的开源代码。

我只是建议这样做根本,因为我不得不处理可笑不合理的类似项目需求。

像这样:

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

while ( <> ) {
   if ( m/<book/ ) { 
       my ( $id ) = ( m/id="(\w+)"/ ); 
       print $id,"\n";
   }
   if ( m/<author/ ) { 
        my ( $author ) = ( m/>(.*)</ );
        print $author,"\n";
   }
}

现在,这个不起作用的原因是您上面的示例可以完全有效地格式化为:

<?xml version="1.0"?>
<catalog><book id="bk101"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications 
      with XML.</description></book><book id="bk102"><author>Ralls, Kim</author><title>Midnight Rain</title><genre>Fantasy</genre><price>5.95</price><publish_date>2000-12-16</publish_date><description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description></book></catalog>

或者

<?xml version="1.0"?>
<catalog>
  <book id="bk101">
    <author>Gambardella, Matthew</author>
    <title>XML Developer's Guide</title>
    <genre>Computer</genre>
    <price>44.95</price>
    <publish_date>2000-10-01</publish_date>
    <description>An in-depth look at creating applications 
      with XML.</description>
  </book>
  <book id="bk102">
    <author>Ralls, Kim</author>
    <title>Midnight Rain</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2000-12-16</publish_date>
    <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
  </book>
</catalog>

或者:

<?xml version="1.0"?>
<catalog
><book
id="bk101"
><author
>Gambardella, Matthew</author><title
>XML Developer's Guide</title><genre
>Computer</genre><price
>44.95</price><publish_date
>2000-10-01</publish_date><description
>An in-depth look at creating applications 
      with XML.</description></book><book
id="bk102"
><author
>Ralls, Kim</author><title
>Midnight Rain</title><genre
>Fantasy</genre><price
>5.95</price><publish_date
>2000-12-16</publish_date><description
>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description></book></catalog>

或者:

<?xml version="1.0"?>

<catalog>
  <book id="bk101"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications 
      with XML.</description></book>
  <book id="bk102"><author>Ralls, Kim</author><title>Midnight Rain</title><genre>Fantasy</genre><price>5.95</price><publish_date>2000-12-16</publish_date><description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description></book>
</catalog>

这就是为什么你有这么多 cmets 说“使用解析器”的原因 - 从上面的那些 sn-ps 中,我给你的简单示例......只会在一个上工作,而在其他方面会混乱。

但是XML::Twig 解决方案可以正确处理它们。 XML::Twig 在 CPAN 上免费提供。 (还有其他库也可以完成这项工作)。它还预装了许多操作系统的“默认”存储库。

【讨论】:

  • 感谢您的回复。不知何故,我设法安装了 XML::Simple 模块,现在我可以在屏幕上打印详细信息了。但现在我有第二个问题,即附加的文档。在检查显示文档路径的一些加密值的 XML 文件时,我已经更新了我的问题,你能说明一下这个问题吗?
  • 如果您有不同的问题,那么我建议您提出不同的问题。我还建议XML::Simple 是最糟糕的选择,但如果这是唯一的选择,可能不会是一场彻底的灾难。
【解决方案2】:

嗯,XML 解析器就是代码。而且CPAN模块都是开源的,所以我想你可以将an XML parsing module from CPAN的代码复制到你的程序中。

但实际上,这是一个非常愚蠢的想法。为什么不直接使用模块?你最好把时间花在移除模块的使用上。许多现代 Perl Perl 编程包括从 CPAN 安装正确的模块并将它们连接在一起。如果您不使用 CPAN 模块,那么您将失去 Perl 的大部分功能。

如果你真的不能解除限制,那么(认真地)找更好的雇主。

【讨论】:

    【解决方案3】:

    如果你不能使用任何模块,那么你应该查看像XML::LibXML这样的模块的源代码,了解它们是如何处理XML的,然后按照你的方式实现它,但不推荐这样做。

    见:Perl for XML Processing

    【讨论】:

    • 如果你不需要的话,我真的不建议去XML::Simple 附近的任何地方。唯一一个好的选择就是如果它是唯一的选择。
    • @Sobrique:啊,我明白了。我已经编辑了答案以包含 XML::LibXML。够好吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-06
    • 2019-11-19
    • 2013-08-25
    • 2014-01-28
    相关资源
    最近更新 更多