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