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