nmake: align with pazpar2 WRT icu/libxslt
[idzebra-moved-to-github.git] / util / idzebra-abs2dom
1 #!/usr/bin/perl -w
2
3 # ----------------------------------------------------------------------------
4 # Generate a dom-filter indexing stylesheet based upon an .abs file
5 # Should be called either this way
6 #
7 #   idzebra-abs2dom something.abs > something.xsl
8 #
9 # or in a streaming way
10 #
11 #   something | idzebra-abs2dom > something.xsl
12 #
13 # The output xslt stylesheet generally needs a little bit of tweaking to be
14 # ready for indexing. In particular, watch out for the precedence rules of
15 # xslt templates which work differently from xelm declarations in an .abs file!
16 #
17 # Good luck!
18
19 use strict;
20
21 my $marc_prefix = 'marc';
22 my $supported_rules = {
23
24         # Supported indexing types:
25         'melm'          => \&melm_handler,
26         'xelm'          => sub { return $_[1] },
27
28         # Declarations to ignore:
29         'attset'        => 0,
30         'encoding'      => 0,
31         'esetname'      => 0,
32         'marc'          => 0,
33         'name'          => 0,
34         'xpath'         => 0
35
36 };
37
38 print <<END_OF_XSLT;
39 <?xml version="1.0"?>
40 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
41                 xmlns:z="http://indexdata.com/zebra-2.0"
42                 xmlns:$marc_prefix="http://www.loc.gov/MARC21/slim"
43                 version="1.0">
44
45   <xsl:output indent="yes"
46         method="xml"
47         version="1.0"
48         encoding="UTF-8"/>
49
50   <xsl:template match="/">
51     <z:record>
52       <xsl:apply-templates/>
53     </z:record>
54   </xsl:template>
55
56 END_OF_XSLT
57
58
59 while (<>) {
60     my $handler = undef;
61
62     chomp;
63     s/^\s+//;
64     s/\s+$//;
65     next unless length;
66     next if /^#/;
67
68     my ($rule) = (/^(\S+)/);
69
70     if ( defined $supported_rules->{$rule} ) {
71         $handler = $supported_rules->{$rule};
72
73         if ( $handler == 0 ) {
74             next;
75         }
76     } else {
77         print STDERR "$0: Unsupported indexing rule: '", $rule, "\n\n";
78         next;
79     }
80
81     s/^\Q$rule\E\s+//;
82
83     my ($index) = (/(\S+)$/);
84
85     s/\s+\Q$index\E$//;
86
87     my $match = $_;
88     my $xpath = $handler->($rule, $match);
89     my @indexes = split /,/, $index;
90
91     # To avoid screwing up the <xsl:template match="...."> instruction...
92     $xpath =~ s/"/'/g;
93
94     print "  <xsl:template match=\"$xpath\">\n";
95     print "    <z:index name=\"", join(" ", @indexes), "\">\n";
96     print "      <xsl:value-of select=\".\"/>\n";
97     print "    </z:index>\n";
98     print "  </xsl:template>\n\n";
99 }
100
101 print "</xsl:stylesheet>\n";
102
103
104 sub melm_handler {
105     my ($rule, $match) = @_;
106     my ($field, $subfield) = ($match =~ /([^\$]+)\$?(.*)/);
107     my $xpath = '/*/';
108
109     if ( $field =~ /^00/ ) {
110         $xpath .= $marc_prefix . ':controlfield[@tag=\'' . $field . '\']';
111     } else {
112         $xpath .= $marc_prefix . ':datafield[@tag=\'' . $field . '\']/' .
113                   $marc_prefix . ':subfield';
114
115         if ( $subfield ne '' ) {
116             $xpath .= '[@code=\'' . $subfield . '\']';
117         }
118     }
119
120     return $xpath;
121 }
122
123
124