0

我正在从 LaTeX 迁移到 PrinceXML。我需要做的一件事是转换参考书目。我已将.bib文件转换为 HTML。然而,由于 LaTeX 为我整理了条目,我没有注意将它们按正确的顺序排列——但在 HTML 中,声明的顺序确实很重要。

所以我的问题是:使用 Linux 命令行工具(例如 Perl 是可以接受的,但 Javascript 不是),我怎样才能像这样对源文件进行排序:

<div id="references">
    <h2>References</h2>

    <ul>
        <li id="reference-to-book-1">
            <span class="ref-author">Sample, Peter</span>
            <cite><a href="http://example.org/">Online Book 1</a></cite>
            <span class="ref-year">2011</span>
        </li>
        <li id="reference-to-book-2">
            <cite>Physical Book 2</cite>
            <span class="ref-year">2012</span>
            <span class="ref-author">Example, Sandy</span>
        </li>
    </ul>
</div><!-- references -->

看起来像这样:

<div id="references">
    <h2>References</h2>

    <ul>
        <li id="reference-to-book-2">
            <span class="ref-author">Example, Sandy</span>
            <cite>Physical Book 2</cite>
            <span class="ref-year">2012</span>
        </li>
        <li id="reference-to-book-1">
            <span class="ref-author">Sample, Peter</span>
            <cite><a href="http://example.org/">Online Book 1</a></cite>
            <span class="ref-year">2011</span>
        </li>
    </ul>
</div><!-- references -->

标准是:

  1. 包含条目的<li>元素根据作者按字母顺序排序(即,从一个<li id="到其对应的所有内容都</li>将作为单个块移动)。
  2. 在每个条目中,元素按以下顺序排列:
    1. 线匹配class="ref-author"
    2. 线匹配<cite>
    3. 线匹配class="ref-year"
    4. class="publisher"为了清楚起见,我在示例中省略了更多元素(例如);另外,我经常遇到这个排序问题。因此,如果可以自由指定要匹配的表达式(例如,作为脚本中的数组声明),将会很有帮助。
  3. 文件的其余部分(外部/id="references"/,/-- references --/)保持不变。
  4. 结果文件的每一行都应该保持不变,除了它在文件中的位置(添加这一点是因为我尝试的 XML 解析器破坏了我的缩进)。

sed我使用and解决了 1、3 和 4 sort,但不能让 2 以这种方式工作。

4

2 回答 2

2

我会为此使用Mojo 。之后您可能需要整理XML。

use Mojo::Base -strict;
use Mojo::DOM;
use Mojo::Util 'slurp';

my $xml = slurp $ARGV[0] or die "I need a file";

my $dom = Mojo::DOM->new($xml);

my $list = $dom->at('#references ul');

my $refs = $dom->find('li');

$refs->each('remove');

$refs = $refs->sort( sub { $a->at('.ref-author')->text cmp $b->at('.ref-author')->text } );

for my $ref ( @{ $refs } ){


    my $new = Mojo::DOM->new('<li></li>')->at('li');
    $new->append_content($ref->at('.ref-author'));
    $new->append_content($ref->at('cite'));

    #KEEP APPENDING IN THE ORDER YOU WANT THEM


    $list->append_content($new);

}

say $dom;
于 2015-05-21T16:02:27.500 回答
0

我建议您使用该XML::LibXML模块并将您的数据解析为 HTML。然后您可以根据需要操作 DOM 并将修改后的结构打印回来

这是它如何工作的示例

use strict;
use warnings;

use XML::LibXML;

my $dom = XML::LibXML->load_html(IO  => \*DATA);

my ($refs) = $dom->findnodes('/html/body//div[@id="references"]/ul');

my @refs = $refs->findnodes('li');

$refs->removeChild($_) for @refs;

$refs->appendChild($_) for sort {
  my ($aa, $bb) = map { $_->findvalue('span[@class="ref-author"]') } $a, $b;
  $aa cmp $bb;
} @refs;

print $dom, "\n";


__DATA__
<html>
  <head>
  <title>Title</title>
  </head>
  <body>
    <div id="references">
        <h2>References</h2>

        <ul>
            <li id="reference-to-book-1">
                <span class="ref-author">Sample, Peter</span>
                <cite><a href="http://example.org/">Online Book 1</a></cite>
                <span class="ref-year">2011</span>
            </li>
            <li id="reference-to-book-2">
                <cite>Physical Book 2</cite>
                <span class="ref-year">2012</span>
                <span class="ref-author">Example, Sandy</span>
            </li>
        </ul>
    </div><!-- references -->
  </body>
</html>

输出

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><head><title>Title</title></head><body>
    <div id="references">
        <h2>References</h2>

        <ul>

        <li id="reference-to-book-2">
                <cite>Physical Book 2</cite>
                <span class="ref-year">2012</span>
                <span class="ref-author">Example, Sandy</span>
            </li><li id="reference-to-book-1">
                <span class="ref-author">Sample, Peter</span>
                <cite><a href="http://example.org/">Online Book 1</a></cite>
                <span class="ref-year">2011</span>
            </li></ul></div><!-- references -->
  </body></html>
于 2015-05-21T13:26:20.100 回答