aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/librarysearch/resultparsers/BASELibraryResultParser.class.php
blob: b92628f1ce64c47f8244a1a531e56b23c290035e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?php
/**
 * This file is part of Stud.IP.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * @author      Moritz Strohm <strohm@data-quest.de>
 * @copyright   2020
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
 * @category    Stud.IP
 * @since       4.6
 */


/**
 * This is a LibraryResultParser implementation for the BASE catalog.
 *
 * @see LibraryResultParser
 */
class BASELibraryResultParser implements LibraryResultParser
{
    /**
     * This is a helper method to index the child nodes of a node which makes
     * accessing them easier. The index is like the "name" attribute
     * of the DOM child node.
     *
     * @param DOMElement $node The node whose child nodes shall be indexed.
     *
     * @returns DOMElement[] An array of DOMElement nodes reperesenting
     * the indexed child nodes of the supplied node.
     */
    protected function indexChildren(\DOMElement $node)
    {
        $indexed_children = [];
        $children = $node->childNodes;
        foreach ($children as $child) {
            $index = $child->getAttribute('name');
            $indexed_children[$index] = $child;
        }
        return $indexed_children;
    }


    /**
     * Reads the XML nodes of one record and creates a LibraryDocument
     * out of it.
     *
     * @param DOMElement $node The XML node of one record.
     *
     * @returns LibraryDocument The LibraryDocument instance that could be read
     *     from the data.
     */
    protected function readXMLRecord(\DOMElement $node) : LibraryDocument
    {
        $result = new LibraryDocument();

        $children = $this->indexChildren($node);

        foreach ($children as $name => $child) {
            if ($child instanceof \DOMElement) {
                if ($name == 'dctypenorm') {
                    //Set the document type by the value of this field.
                    $base_typeid = trim($child->textContent);
                    if ($base_typeid == '11' || $base_typeid == '111') {
                        $result->type = 'book';
                    } elseif ($base_typeid == '12' || $base_typeid == '121' || $base_typeid == '122') {
                        $result->type = 'article';
                    } elseif ($base_typeid == '13') {
                        $result->type = 'paper-conference';
                    } elseif ($base_typeid == '14') {
                        $result->type = 'report';
                    } else {
                        $result->type = $base_typeid;
                    }
                } elseif ($name == 'dctitle') {
                    $result->csl_data['title'] = $child->textContent;
                } elseif ($name == 'dccreator') {
                    $authors = $child->getElementsByTagName('str');
                    $csl_authors = [];
                    foreach ($authors as $author) {
                        $author_names = explode(', ', $author->textContent);
                        $csl_authors[] = [
                            'family' => $author_names[0],
                            'given' => $author_names[1],
                            'suffix' => ''
                        ];
                    }
                    $result->csl_data['author'] = $csl_authors;
                } elseif ($name == 'dcdate') {
                    $date_and_time = explode('T', $child->textContent);
                    $date_parts = explode('-', $date_and_time[0]);
                    $result->csl_data['issued'] = ['date-parts' => [$date_parts]];
                } elseif (($name == 'dcyear') && !($result->csl_data['issued'])) {
                    $result->csl_data['issued'] = ['date-parts' => [$child->textContent]];
                } elseif ($name == 'dcdescription') {
                    $result->csl_data['abstract'] = $child->textContent;
                } elseif ($name == 'dcpublisher') {
                    $str = $child->childNodes[0];
                    if ($str instanceof \DOMElement) {
                        $result->csl_data['publisher'] = $str->textContent;
                    }
                } elseif ($name == 'dclink') {
                    $result->csl_data['URL'] = $child->textContent;
                } elseif ($name == 'dcdocid') {
                    $result->csl_data['DOI'] = $child->textContent;
                } else {
                    //All other field values are stored in the datafields array.
                    $result->datafields[$name] = $child->textContent;
                }
            }
        }
        return $result;
    }


    /**
     * @see LibraryResultParser::readResultSet
     */
    public function readResultSet($data = '') : array
    {
        if (!$data) {
            return [];
        }
        $dom = new \DOMDocument();
        @$dom->loadXML($data);
        $result = $dom->getElementsByTagName('response')[0];
        if (!$result) {
            //Wrong document type.
            return [];
        }

        $documents = $result->getElementsByTagName('doc');
        $result_set = [];
        foreach ($documents as $document) {
            $result_set[] = $this->readXMLRecord($document);
        }
        return $result_set;
    }


    /**
     * @see LibraryResultParser::readRecord
     */
    public function readRecord($data = ''): LibraryDocument
    {
        $dom = new DOMDocument();
        @$dom->loadXML($data);
        $record = $dom->getElementsByTagName('doc')[0];
        if ($record) {
           return $this->readXMLRecord($record);
        }

        throw new Exception('Could not read record');
    }
}