如何在XML :: Simple的输出中订购标签?

Mor*_*nar 3 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,但肯定会感谢有人可能有的任何技巧/想法.谢谢.

Rob*_*t P 11

大多数时候配置只需要XML::Simple提供的选项即可完成.通常,它会自动将数据折叠成数据结构的简单,可以逻辑再现; 它非常适合数据存储格式,但在匹配文档格式方面却不那么强大.幸运的是,即使它"简单",它也非常强大.

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

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

但很多时候,特别是对于非常具体的模式,这是行不通的.幸运的是,XML :: Simple仍然支持一种自定义方式:必须使用OO接口,并覆盖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";
Run Code Online (Sandbox Code Playgroud)

这将给我们:

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'
                                    }
                        }
        };
Run Code Online (Sandbox Code Playgroud)

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

  • 我们在项目中实现了这个解决方案,但是在调试时要非常小心:标签中存在简单的输入错误,XML-hash中存在但不存在于分类器中的标签,以及输出XML中的标签"dissapears"!遗憾的是,您必须列出分拣机中的所有标签,并且不能只编写一些排序的代码(例如perl`sort`),以便覆盖未来的元素.结论:可以随意使用这种技术进行快速和肮脏的操作,但我不建议将它用于更大的项目或将来容易发生变化的事情. (2认同)