Remove redundant header includes
[yaz-moved-to-github.git] / src / xml_match.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2013 Index Data
3  * See the file LICENSE for details.
4  */
5 /**
6  * \file xml_match.c
7  * \brief XML node inspection utilities
8  */
9 #if HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <yaz/srw.h>
14 #if YAZ_HAVE_XML2
15 #include "sru-p.h"
16
17 int yaz_match_xsd_element(xmlNodePtr ptr, const char *elem)
18 {
19     if (ptr->type == XML_ELEMENT_NODE && !xmlStrcmp(ptr->name, BAD_CAST elem))
20     {
21         return 1;
22     }
23     return 0;
24 }
25
26 #define CHECK_TYPE 0
27
28 int yaz_match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o,
29                            char **val, int *len)
30 {
31 #if CHECK_TYPE
32     struct _xmlAttr *attr;
33 #endif
34     if (!yaz_match_xsd_element(ptr, elem))
35         return 0;
36 #if CHECK_TYPE
37     for (attr = ptr->properties; attr; attr = attr->next)
38         if (!strcmp(attr->name, "type") &&
39             attr->children && attr->children->type == XML_TEXT_NODE)
40         {
41             const char *t = strchr(attr->children->content, ':');
42             if (t)
43                 t = t + 1;
44             else
45                 t = attr->children->content;
46             if (!strcmp(t, "string"))
47                 break;
48         }
49     if (!attr)
50         return 0;
51 #endif
52     ptr = ptr->children;
53     if (!ptr || ptr->type != XML_TEXT_NODE)
54     {
55         *val = "";
56         return 1;
57     }
58     *val = odr_strdup(o, (const char *) ptr->content);
59     if (len)
60         *len = xmlStrlen(ptr->content);
61     return 1;
62 }
63
64
65 int yaz_match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o, char **val)
66 {
67     return yaz_match_xsd_string_n(ptr, elem, o, val, 0);
68 }
69
70 int yaz_match_xsd_XML_n2(xmlNodePtr ptr, const char *elem, ODR o,
71                          char **val, int *len, int fixup_root)
72 {
73     xmlBufferPtr buf;
74     int no_root_nodes = 0;
75
76     if (!yaz_match_xsd_element(ptr, elem))
77         return 0;
78
79     buf = xmlBufferCreate();
80
81     /* Copy each element nodes at top.
82        In most cases there is only one root node.. At least one server
83        http://www.theeuropeanlibrary.org/sru/sru.pl
84        has multiple root nodes in recordData.
85     */
86     for (ptr = ptr->children; ptr; ptr = ptr->next)
87     {
88         if (ptr->type == XML_ELEMENT_NODE)
89         {
90             /* copy node to get NS right (bug #740). */
91             xmlNode *tmp = xmlCopyNode(ptr, 1);
92
93             xmlNodeDump(buf, tmp->doc, tmp, 0, 0);
94
95             xmlFreeNode(tmp);
96             no_root_nodes++;
97         }
98     }
99     if (no_root_nodes != 1 && fixup_root)
100     {
101         /* does not appear to be an XML document. Make it so */
102         xmlBufferAddHead(buf, (const xmlChar *) "<yaz_record>", -1);
103         xmlBufferAdd(buf, (const xmlChar *) "</yaz_record>", -1);
104     }
105     *val = (char *) odr_malloc(o, buf->use + 1);
106     memcpy(*val, buf->content, buf->use);
107     (*val)[buf->use] = '\0';
108
109     if (len)
110         *len = buf->use;
111
112     xmlBufferFree(buf);
113
114     return 1;
115 }
116
117 int yaz_match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,
118                         char **val, int *len)
119 {
120     return yaz_match_xsd_XML_n2(ptr, elem, o, val, len, 0);
121 }
122
123 int yaz_match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o,
124                           Odr_int **val)
125 {
126 #if CHECK_TYPE
127     struct _xmlAttr *attr;
128 #endif
129     if (!yaz_match_xsd_element(ptr, elem))
130         return 0;
131 #if CHECK_TYPE
132     for (attr = ptr->properties; attr; attr = attr->next)
133         if (!strcmp(attr->name, "type") &&
134             attr->children && attr->children->type == XML_TEXT_NODE)
135         {
136             const char *t = strchr(attr->children->content, ':');
137             if (t)
138                 t = t + 1;
139             else
140                 t = attr->children->content;
141             if (!strcmp(t, "integer"))
142                 break;
143         }
144     if (!attr)
145         return 0;
146 #endif
147     ptr = ptr->children;
148     if (!ptr || ptr->type != XML_TEXT_NODE)
149         return 0;
150     *val = odr_intdup(o, odr_atoi((const char *) ptr->content));
151     return 1;
152 }
153
154
155 #endif
156
157
158 /*
159  * Local variables:
160  * c-basic-offset: 4
161  * c-file-style: "Stroustrup"
162  * indent-tabs-mode: nil
163  * End:
164  * vim: shiftwidth=4 tabstop=8 expandtab
165  */
166