xml - 如何在 XML::Simple 的输出中对标签进行排序?

标签 xml perl

这是我的场景:

我需要通过 Perl 生成 XML,其中模式充满了 <xs:sequence>标签(即标签必须按顺序出现)。我无法控制模式(第三方),每当我们添加新的 CPAN 模块(没有将它们传播给客户等的好方法等)时,我们基本上被禁止添加任何新内容(如 XML::Writer )。

我可以使用的 XML 模块是:XML::Parser , XML::Simple , XML::XPath .

我很喜欢XML::Simple中的方式你创建一个 hashref w/hash/arary refs 数据结构,然后只是吐出 XML。

有没有用 XML::Simple 做的呢? ?或者也许滚动我自己的代码以按顺序吐出 XML?似乎我最大的问题是我需要按插入顺序从 hashref 中提取内容,而 Perl 并没有真正做到那么好。我确实读过 Tie::IxHash用于按插入顺序拉出内容,但同样是我没有的模块。

感觉我有点像 SOL,但肯定会很感激有人可能有的任何技巧/想法。谢谢。

最佳答案

大多数情况下,只需使用 XML::Simple 提供的选项即可完成配置。通常,它会自动将数据折叠成可以逻辑复制的最简单的数据结构;它非常适合数据存储格式,但在匹配文档格式方面却不那么强大。幸运的是,尽管它“简单”,但它却非常强大。

要控制元素的输出顺序,您有几个选项。您可以使用保证数据顺序的数组。但是,您似乎需要一个标签的特定顺序的值。

键排序也是一项自动功能。只要您拥有的键是按字母顺序排列的,它们就会保证按特定顺序排序。

但很多时候,尤其是对于非常具体的架构,这是行不通的。幸运的是,XML::Simple 仍然支持自定义它的方法:您必须使用 OO 接口(interface),并覆盖 sorted_keys 方法。这是一个例子:

use strict;
use warnings;
use XML::Simple;
use Data::Dumper;

package MyXMLSimple;      # my XML::Simple subclass 
use base 'XML::Simple';

# Overriding the method here
sub sorted_keys
{
   my ($self, $name, $hashref) = @_;
   if ($name eq 'supertag')   # only this tag I care about the order;
   {
      return ('tag1', 'tag3','tag4','tag10'); # so I specify exactly the right order.
   }
   return $self->SUPER::sorted_keys($name, $hashref); # for the rest, I don't care!
}

package main; # back to main code

my $xmlParser = MyXMLSimple->new(      # Create the parser, with options:
                  KeepRoot => 1,       # gives us our root element always.
                  ForceContent => 1,   # ensures that content stays special
               );

my $structure = { 
   supertag => { 
      tag1  => { content => 'value 1' },
      tag10 => { content => 'value 2' },
      tag3  => { content => 'value 3' },
      tag4  => { content => 'value 4' },
   },
};

my $xml = $xmlParser->XMLout($structure);
print "The xml generated is:\n$xml\n";
print "The read in structure then is:\n" . $xmlParser->XMLin($xml) . "\n";

这会给我们:

The xml generated is:
<supertag>
  <tag1>value 1</tag1>
  <tag3>value 3</tag3>
  <tag4>value 4</tag4>
  <tag10>value 2</tag10>
</supertag>

The read in structure then is:
$VAR1 = {
          'supertag' => {
                          'tag10' => {
                                       'content' => 'value 2'
                                     },
                          'tag3' => {
                                      'content' => 'value 3'
                                    },
                          'tag1' => {
                                      'content' => 'value 1'
                                    },
                          'tag4' => {
                                      'content' => 'value 4'
                                    }
                        }
        };

查看 XML::Simple CPAN 上的页面。

关于xml - 如何在 XML::Simple 的输出中对标签进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1400850/

相关文章:

java - cvc-复杂-类型.3.2.2 : Attribute 'xsi:schemalocation' is not allowed to appear in element 'jtis_journey_list'

c# - 反序列化不起作用

iphone - 如何使用 Xcode 从服务器读取 webService?

javascript - 将 Javascript 变量转换为 Coldfusion 变量

perl - Perl6 是否支持与 Perl5 的 __DATA__ 和 __END__ 部分等效的内容?

c# - 尝试将 xml 导入 android 时出现 OutOfMemoryException

python - 外壳 : insert a blank/new line two lines above pattern

perl - 从 teamcity 构建中获取工件列表并仅下载确切的一个

perl - 如何引用 Perl 中的数组切片?

perl - 使用命令行替换文件夹中所有文件中的文本?