按XML元素的属性值排序

tch*_*ike 0 xml sorting perl xml-simple xml-libxml

我有以下XML

<?xml version="1.0" encoding="UTF-8"?>  
  <Objects >
    <Item1 elemId="id1" name="view" sort_id="3">
    </Item1>
    <Item2 elemId="id3" name="view" sort_id="4" >
    </Item2>
    <Item3 elemId="id5" name="view" sort_id="2">
    </Item3>
    <Item4 elemId="id9" name="view" sort_id="1">
    </Item4>
  </Objects>
Run Code Online (Sandbox Code Playgroud)

我想通过属性对该数据进行排序sort_id以获取以下内容:

<?xml version="1.0" encoding="UTF-8"?>  
  <Objects >
    <Item4 elemId="id9" name="view" sort_id="1">
    </Item4>
    <Item3 elemId="id5" name="view" sort_id="2">
    </Item3>
    <Item1 elemId="id1" name="view" sort_id="3">
    </Item1>
    <Item2 elemId="id3" name="view" sort_id="4" >
    </Item2>
  </Objects>
Run Code Online (Sandbox Code Playgroud)

我知道我不能这样做XML::Simple,但我听说我可以接受XML::LibXML。我找不到解决方案。

Bor*_*din 5

没有内置XML::LibXML专门用于排序元素的内容,但是使用可用的API却很简单

这样的事情会做你想要的。不幸的XML::LibXML是,尽管它的格式正确且有效,但它并不能很好地产生整洁的输出。如果您想要更漂亮的东西,那么应该看看XML::LibXML::PrettyPrint,它将为您完成此操作

use strict;
use warnings 'all';

use XML::LibXML;

my $doc = XML::LibXML->load_xml(location => 'sort_xml.xml');

my ($objects) = $doc->findnodes('/Objects');

my @items = $objects->findnodes('*');
@items = sort {
    $a->getAttribute('sort_id') <=> $b->getAttribute('sort_id')
} @items;

$objects->removeChildNodes;
$objects->appendChild( $_ ) for @items;

print $doc;
Run Code Online (Sandbox Code Playgroud)

输出

<?xml version="1.0" encoding="UTF-8"?>
<Objects><Item4 elemId="id9" name="view" sort_id="1">
    </Item4><Item3 elemId="id5" name="view" sort_id="2">
    </Item3><Item1 elemId="id1" name="view" sort_id="3">
    </Item1><Item2 elemId="id3" name="view" sort_id="4">
    </Item2></Objects>
Run Code Online (Sandbox Code Playgroud)

更新资料

要使用XML::LibXML::PrettyPrint,您需要添加

use XML::LibXML::PrettyPrint;
Run Code Online (Sandbox Code Playgroud)

在程序顶部,然后替换

print $doc;
Run Code Online (Sandbox Code Playgroud)

my $pp = XML::LibXML::PrettyPrint->new(indent_string => "  ");
$pp->pretty_print($doc);
print $doc;
Run Code Online (Sandbox Code Playgroud)

输出

<?xml version="1.0" encoding="UTF-8"?>
<Objects>
  <Item4 elemId="id9" name="view" sort_id="1"/>
  <Item3 elemId="id5" name="view" sort_id="2"/>
  <Item1 elemId="id1" name="view" sort_id="3"/>
  <Item2 elemId="id3" name="view" sort_id="4"/>
</Objects>
Run Code Online (Sandbox Code Playgroud)